← back to Model Arena
night-loop: cycle 23:19 — judged=4a6e2cfce746 · (backlog 2 — skipped fire)
5917c150983743485673958bf11c7e2ff5c20438 · 2026-07-24 23:19:46 -0700 · Steve Abrams
Files touched
A data/artifacts/dfaee602df0d/claude-code.htmlA data/artifacts/dfaee602df0d/claude-code.pngA data/artifacts/dfaee602df0d/qwen25-7b.htmlA data/artifacts/dfaee602df0d/qwen25-7b.pngA data/artifacts/ea271db82cff/qwen25-7b.htmlA data/artifacts/ea271db82cff/qwen25-7b.pngA data/artifacts/ea271db82cff/qwen3-14b.htmlA data/artifacts/ea271db82cff/qwen3-14b.pngM data/challenges.jsonA data/landings/10c3c876aa67-grok.htmlA idea-run/night-cycle.sh
Diff
commit 5917c150983743485673958bf11c7e2ff5c20438
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Jul 24 23:19:46 2026 -0700
night-loop: cycle 23:19 — judged=4a6e2cfce746 · (backlog 2 — skipped fire)
---
data/artifacts/dfaee602df0d/claude-code.html | 473 +++++++++++++++++++++++++++
data/artifacts/dfaee602df0d/claude-code.png | Bin 0 -> 207113 bytes
data/artifacts/dfaee602df0d/qwen25-7b.html | 86 +++++
data/artifacts/dfaee602df0d/qwen25-7b.png | Bin 0 -> 6336 bytes
data/artifacts/ea271db82cff/qwen25-7b.html | 196 +++++++++++
data/artifacts/ea271db82cff/qwen25-7b.png | Bin 0 -> 6780 bytes
data/artifacts/ea271db82cff/qwen3-14b.html | 444 +++++++++++++++++++++++++
data/artifacts/ea271db82cff/qwen3-14b.png | Bin 0 -> 197948 bytes
data/challenges.json | 53 +--
data/landings/10c3c876aa67-grok.html | 222 +++++++++++++
idea-run/night-cycle.sh | 43 +++
11 files changed, 1494 insertions(+), 23 deletions(-)
diff --git a/data/artifacts/dfaee602df0d/claude-code.html b/data/artifacts/dfaee602df0d/claude-code.html
new file mode 100644
index 0000000..fb8fdfb
--- /dev/null
+++ b/data/artifacts/dfaee602df0d/claude-code.html
@@ -0,0 +1,473 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Agent Swarm // Snake</title>
+<style>
+ :root{
+ --bg:#05070d;
+ --grid:#0c1220;
+ --neon:#00e5ff;
+ --neon2:#7cff6b;
+ --task:#ff2fb0;
+ --task2:#ffd84a;
+ --ink:#cde8ff;
+ --dim:#4a6a86;
+ --danger:#ff3b5c;
+ }
+ *{box-sizing:border-box;margin:0;padding:0}
+ html,body{height:100%}
+ body{
+ background:
+ radial-gradient(1200px 700px at 50% -10%, #0a1830 0%, transparent 60%),
+ radial-gradient(900px 600px at 90% 110%, #180a2e 0%, transparent 55%),
+ var(--bg);
+ color:var(--ink);
+ font-family:'Segoe UI',Roboto,-apple-system,system-ui,sans-serif;
+ display:flex;flex-direction:column;align-items:center;justify-content:center;
+ min-height:100%;
+ overflow:hidden;
+ -webkit-font-smoothing:antialiased;
+ }
+ .wrap{
+ display:flex;flex-direction:column;align-items:center;gap:14px;
+ padding:18px;
+ }
+ header{
+ display:flex;flex-direction:column;align-items:center;gap:2px;
+ }
+ h1{
+ font-size:22px;font-weight:800;letter-spacing:3px;
+ text-transform:uppercase;
+ background:linear-gradient(90deg,var(--neon),var(--neon2));
+ -webkit-background-clip:text;background-clip:text;color:transparent;
+ filter:drop-shadow(0 0 10px rgba(0,229,255,.35));
+ }
+ .sub{font-size:10px;letter-spacing:4px;color:var(--dim);text-transform:uppercase}
+
+ .hud{
+ display:flex;gap:10px;flex-wrap:wrap;justify-content:center;width:100%;
+ }
+ .card{
+ background:rgba(10,20,36,.7);
+ border:1px solid rgba(0,229,255,.18);
+ border-radius:10px;
+ padding:8px 14px;min-width:96px;text-align:center;
+ box-shadow:inset 0 0 20px rgba(0,229,255,.05);
+ backdrop-filter:blur(4px);
+ }
+ .card .lbl{font-size:9px;letter-spacing:2px;color:var(--dim);text-transform:uppercase}
+ .card .val{font-size:20px;font-weight:800;color:var(--neon);text-shadow:0 0 12px rgba(0,229,255,.5)}
+ .card.alt .val{color:var(--neon2);text-shadow:0 0 12px rgba(124,255,107,.5)}
+ .card.tok .val{color:var(--task);text-shadow:0 0 12px rgba(255,47,176,.5)}
+
+ .stage{position:relative}
+ canvas{
+ display:block;
+ border-radius:14px;
+ border:1px solid rgba(0,229,255,.25);
+ box-shadow:0 0 40px rgba(0,229,255,.12), inset 0 0 60px rgba(0,0,0,.6);
+ background:var(--grid);
+ touch-action:none;
+ }
+ .overlay{
+ position:absolute;inset:0;
+ display:flex;flex-direction:column;align-items:center;justify-content:center;
+ gap:14px;text-align:center;
+ background:radial-gradient(circle at 50% 45%, rgba(6,10,20,.72), rgba(3,5,10,.92));
+ border-radius:14px;
+ backdrop-filter:blur(3px);
+ transition:opacity .25s ease;
+ }
+ .overlay.hide{opacity:0;pointer-events:none}
+ .overlay h2{
+ font-size:30px;font-weight:900;letter-spacing:2px;text-transform:uppercase;
+ background:linear-gradient(90deg,var(--neon),var(--task));
+ -webkit-background-clip:text;background-clip:text;color:transparent;
+ filter:drop-shadow(0 0 14px rgba(255,47,176,.35));
+ }
+ .overlay p{font-size:12px;color:var(--dim);max-width:320px;line-height:1.6;letter-spacing:.5px}
+ .overlay .big{font-size:14px;color:var(--ink)}
+ .keys{display:flex;gap:6px;flex-wrap:wrap;justify-content:center;margin-top:4px}
+ .key{
+ font-size:10px;letter-spacing:1px;color:var(--neon);
+ border:1px solid rgba(0,229,255,.3);border-radius:6px;padding:4px 8px;
+ background:rgba(0,229,255,.06);
+ }
+ button{
+ margin-top:8px;
+ font-family:inherit;font-size:12px;font-weight:800;letter-spacing:2px;
+ text-transform:uppercase;color:#03121a;cursor:pointer;
+ background:linear-gradient(90deg,var(--neon),var(--neon2));
+ border:none;border-radius:9px;padding:12px 28px;
+ box-shadow:0 0 24px rgba(0,229,255,.35);
+ transition:transform .1s ease, box-shadow .2s ease;
+ }
+ button:hover{transform:translateY(-2px);box-shadow:0 0 34px rgba(0,229,255,.55)}
+ button:active{transform:translateY(0)}
+ .foot{font-size:10px;color:var(--dim);letter-spacing:2px}
+</style>
+</head>
+<body>
+ <div class="wrap">
+ <header>
+ <h1>Agent Swarm</h1>
+ <div class="sub">distributed task-collection protocol</div>
+ </header>
+
+ <div class="hud">
+ <div class="card"><div class="lbl">Score</div><div class="val" id="score">0</div></div>
+ <div class="card tok"><div class="lbl">Tokens Processed</div><div class="val" id="tokens">0</div></div>
+ <div class="card alt"><div class="lbl">Swarm Size</div><div class="val" id="size">1</div></div>
+ <div class="card"><div class="lbl">Best</div><div class="val" id="best">0</div></div>
+ </div>
+
+ <div class="stage">
+ <canvas id="game" width="520" height="520"></canvas>
+ <div class="overlay" id="overlay">
+ <h2 id="ovTitle">Deploy Swarm</h2>
+ <p id="ovText">Steer your chain of glowing agent nodes across the grid. Consume pulsing <b style="color:var(--task)">task tokens</b> — each one grows the swarm and increments tokens processed. Avoid colliding with your own agents.</p>
+ <div class="keys">
+ <span class="key">↑ ← ↓ →</span><span class="key">W A S D</span><span class="key">SPACE pause</span>
+ </div>
+ <button id="startBtn">Initialize</button>
+ </div>
+ </div>
+
+ <div class="foot">60fps · no external assets · self-collision = protocol failure</div>
+ </div>
+
+<script>
+(() => {
+ const canvas = document.getElementById('game');
+ const ctx = canvas.getContext('2d');
+ const COLS = 26, ROWS = 26;
+ const CELL = canvas.width / COLS;
+
+ const el = {
+ score: document.getElementById('score'),
+ tokens: document.getElementById('tokens'),
+ size: document.getElementById('size'),
+ best: document.getElementById('best'),
+ overlay: document.getElementById('overlay'),
+ ovTitle: document.getElementById('ovTitle'),
+ ovText: document.getElementById('ovText'),
+ startBtn: document.getElementById('startBtn'),
+ };
+
+ let snake, dir, nextDir, task, score, tokens, best = 0;
+ let state = 'menu'; // menu | playing | paused | dead
+ let moveInterval = 120; // ms per grid step (movement logic)
+ let acc = 0, last = 0;
+ let prevSnake = []; // positions at start of current step (for interpolation)
+ let particles = [];
+ let shake = 0;
+ let taskPulse = 0;
+
+ function reset() {
+ const cx = Math.floor(COLS/2), cy = Math.floor(ROWS/2);
+ snake = [{x:cx,y:cy},{x:cx-1,y:cy},{x:cx-2,y:cy}];
+ prevSnake = snake.map(s => ({...s}));
+ dir = {x:1,y:0};
+ nextDir = {x:1,y:0};
+ score = 0; tokens = 0;
+ moveInterval = 120;
+ particles = [];
+ spawnTask();
+ updateHUD();
+ }
+
+ function spawnTask() {
+ let p;
+ do {
+ p = { x: Math.floor(Math.random()*COLS), y: Math.floor(Math.random()*ROWS) };
+ } while (snake.some(s => s.x===p.x && s.y===p.y));
+ task = p;
+ }
+
+ function updateHUD() {
+ el.score.textContent = score;
+ el.tokens.textContent = tokens;
+ el.size.textContent = snake.length;
+ el.best.textContent = best;
+ }
+
+ function step() {
+ prevSnake = snake.map(s => ({...s}));
+ dir = nextDir;
+ const head = snake[0];
+ const nx = head.x + dir.x;
+ const ny = head.y + dir.y;
+
+ // wall wrap? No — walls are collisions via bounds -> game over on edge would be harsh;
+ // classic feel: hitting wall ends run.
+ if (nx < 0 || nx >= COLS || ny < 0 || ny >= ROWS) { die(); return; }
+
+ // self collision (ignore tail cell that will move away unless growing)
+ for (let i = 0; i < snake.length - 1; i++) {
+ if (snake[i].x === nx && snake[i].y === ny) { die(); return; }
+ }
+
+ const newHead = {x:nx, y:ny};
+ snake.unshift(newHead);
+
+ if (nx === task.x && ny === task.y) {
+ score += 10;
+ tokens += 1 + Math.floor(snake.length/4);
+ burst(task.x, task.y);
+ shake = 6;
+ if (moveInterval > 65) moveInterval -= 2.2;
+ spawnTask();
+ } else {
+ snake.pop();
+ }
+ updateHUD();
+ }
+
+ function die() {
+ state = 'dead';
+ shake = 16;
+ for (const s of snake) burst(s.x, s.y, true);
+ if (score > best) best = score;
+ updateHUD();
+ el.ovTitle.textContent = 'Protocol Failure';
+ el.ovText.innerHTML = `The swarm collapsed at <b style="color:var(--neon2)">${snake.length}</b> agents.<br>Score <b style="color:var(--neon)">${score}</b> · Tokens processed <b style="color:var(--task)">${tokens}</b>.`;
+ el.startBtn.textContent = 'Redeploy';
+ el.overlay.classList.remove('hide');
+ }
+
+ function burst(gx, gy, red=false) {
+ const px = gx*CELL + CELL/2, py = gy*CELL + CELL/2;
+ const n = red ? 5 : 12;
+ for (let i=0;i<n;i++){
+ const a = Math.random()*Math.PI*2;
+ const sp = 0.6 + Math.random()*2.2;
+ particles.push({
+ x:px, y:py,
+ vx:Math.cos(a)*sp, vy:Math.sin(a)*sp,
+ life:1, r:1.5+Math.random()*2.5,
+ red
+ });
+ }
+ }
+
+ // ---- Rendering ----
+ function drawGrid() {
+ ctx.strokeStyle = 'rgba(0,229,255,0.045)';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ for (let i=0;i<=COLS;i++){
+ ctx.moveTo(i*CELL+.5,0); ctx.lineTo(i*CELL+.5,canvas.height);
+ }
+ for (let j=0;j<=ROWS;j++){
+ ctx.moveTo(0,j*CELL+.5); ctx.lineTo(canvas.width,j*CELL+.5);
+ }
+ ctx.stroke();
+ }
+
+ function lerp(a,b,t){ return a + (b-a)*t; }
+
+ function render(t) {
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+
+ ctx.save();
+ if (shake > 0) {
+ ctx.translate((Math.random()-.5)*shake, (Math.random()-.5)*shake);
+ }
+
+ drawGrid();
+
+ // task token (pulsing)
+ taskPulse += 0.08;
+ if (task) {
+ const tx = task.x*CELL + CELL/2, ty = task.y*CELL + CELL/2;
+ const pulse = 0.5 + Math.sin(taskPulse)*0.5;
+ const rad = CELL*0.34 + pulse*CELL*0.14;
+ const g = ctx.createRadialGradient(tx,ty,0,tx,ty,rad*2.2);
+ g.addColorStop(0,'rgba(255,47,176,0.9)');
+ g.addColorStop(0.4,'rgba(255,216,74,0.4)');
+ g.addColorStop(1,'rgba(255,47,176,0)');
+ ctx.fillStyle = g;
+ ctx.beginPath(); ctx.arc(tx,ty,rad*2.2,0,Math.PI*2); ctx.fill();
+
+ ctx.fillStyle = '#ffd84a';
+ ctx.shadowColor = '#ff2fb0'; ctx.shadowBlur = 18;
+ ctx.beginPath(); ctx.arc(tx,ty,rad*0.6,0,Math.PI*2); ctx.fill();
+ ctx.shadowBlur = 0;
+ }
+
+ // interpolation factor for smooth movement
+ const it = (state === 'playing') ? Math.min(1, acc / moveInterval) : 1;
+
+ // snake as connecting glowing chain
+ const pts = [];
+ for (let i=0;i<snake.length;i++){
+ const cur = snake[i];
+ const prev = prevSnake[i] || cur;
+ const x = lerp(prev.x, cur.x, it)*CELL + CELL/2;
+ const y = lerp(prev.y, cur.y, it)*CELL + CELL/2;
+ pts.push({x,y});
+ }
+
+ // connective link
+ if (pts.length > 1) {
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeStyle = 'rgba(0,229,255,0.28)';
+ ctx.lineWidth = CELL*0.7;
+ ctx.shadowColor = '#00e5ff'; ctx.shadowBlur = 14;
+ ctx.beginPath();
+ ctx.moveTo(pts[0].x,pts[0].y);
+ for (let i=1;i<pts.length;i++) ctx.lineTo(pts[i].x,pts[i].y);
+ ctx.stroke();
+ ctx.shadowBlur = 0;
+ }
+
+ // agent nodes
+ for (let i=pts.length-1;i>=0;i--){
+ const p = pts[i];
+ const head = i===0;
+ const frac = i/Math.max(1,pts.length);
+ const baseR = head ? CELL*0.44 : CELL*0.30*(1-frac*0.35);
+ // color gradient from cyan head to green tail
+ const c1 = head ? '#aef8ff' : mix('#00e5ff','#7cff6b',frac);
+ const c2 = head ? '#00e5ff' : mix('#0090c0','#3fae4a',frac);
+
+ const g = ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,baseR*1.6);
+ g.addColorStop(0,c1);
+ g.addColorStop(0.6,c2);
+ g.addColorStop(1,'rgba(0,20,30,0)');
+ ctx.fillStyle = g;
+ ctx.beginPath(); ctx.arc(p.x,p.y,baseR*1.6,0,Math.PI*2); ctx.fill();
+
+ ctx.fillStyle = c1;
+ ctx.beginPath(); ctx.arc(p.x,p.y,baseR*0.55,0,Math.PI*2); ctx.fill();
+
+ // head "eye" indicating direction
+ if (head) {
+ ctx.fillStyle = '#031018';
+ const ex = p.x + dir.x*baseR*0.4;
+ const ey = p.y + dir.y*baseR*0.4;
+ ctx.beginPath(); ctx.arc(ex,ey,baseR*0.16,0,Math.PI*2); ctx.fill();
+ }
+ }
+
+ // particles
+ for (const pr of particles) {
+ ctx.globalAlpha = Math.max(0,pr.life);
+ ctx.fillStyle = pr.red ? '#ff3b5c' : '#ffd84a';
+ ctx.beginPath(); ctx.arc(pr.x,pr.y,pr.r,0,Math.PI*2); ctx.fill();
+ }
+ ctx.globalAlpha = 1;
+
+ ctx.restore();
+ }
+
+ function mix(a,b,t){
+ const pa=[parseInt(a.slice(1,3),16),parseInt(a.slice(3,5),16),parseInt(a.slice(5,7),16)];
+ const pb=[parseInt(b.slice(1,3),16),parseInt(b.slice(3,5),16),parseInt(b.slice(5,7),16)];
+ const r=Math.round(lerp(pa[0],pb[0],t));
+ const g=Math.round(lerp(pa[1],pb[1],t));
+ const bl=Math.round(lerp(pa[2],pb[2],t));
+ return `rgb(${r},${g},${bl})`;
+ }
+
+ // ---- Main loop (60fps via rAF) ----
+ function loop(ts) {
+ const dt = Math.min(50, ts - last || 0);
+ last = ts;
+
+ if (state === 'playing') {
+ acc += dt;
+ while (acc >= moveInterval) {
+ acc -= moveInterval;
+ step();
+ if (state !== 'playing') break;
+ }
+ }
+
+ // update particles + shake every frame
+ for (let i=particles.length-1;i>=0;i--){
+ const pr=particles[i];
+ pr.x+=pr.vx; pr.y+=pr.vy;
+ pr.vx*=0.94; pr.vy*=0.94;
+ pr.life-=0.03;
+ if (pr.life<=0) particles.splice(i,1);
+ }
+ if (shake>0) shake*=0.86;
+ if (shake<0.3) shake=0;
+
+ render(ts);
+ requestAnimationFrame(loop);
+ }
+
+ // ---- Input ----
+ const DIRS = {
+ ArrowUp:{x:0,y:-1}, ArrowDown:{x:0,y:1}, ArrowLeft:{x:-1,y:0}, ArrowRight:{x:1,y:0},
+ w:{x:0,y:-1}, s:{x:0,y:1}, a:{x:-1,y:0}, d:{x:1,y:0},
+ W:{x:0,y:-1}, S:{x:0,y:1}, A:{x:-1,y:0}, D:{x:1,y:0}
+ };
+
+ window.addEventListener('keydown', (e) => {
+ if (e.key === ' ') {
+ e.preventDefault();
+ if (state === 'playing') { state='paused'; showOverlay('Paused','Swarm on standby. Press SPACE or Resume.','Resume'); }
+ else if (state === 'paused') { hideOverlay(); state='playing'; }
+ return;
+ }
+ if (e.key === 'Enter' && state !== 'playing') { start(); return; }
+ const nd = DIRS[e.key];
+ if (nd) {
+ e.preventDefault();
+ // prevent 180° reversal
+ if (nd.x === -dir.x && nd.y === -dir.y) return;
+ if (nd.x === dir.x && nd.y === dir.y) return;
+ nextDir = nd;
+ }
+ }, {passive:false});
+
+ // touch / swipe
+ let touchStart = null;
+ canvas.addEventListener('touchstart', e => {
+ touchStart = {x:e.touches[0].clientX, y:e.touches[0].clientY};
+ }, {passive:true});
+ canvas.addEventListener('touchmove', e => {
+ if (!touchStart) return;
+ const dx = e.touches[0].clientX - touchStart.x;
+ const dy = e.touches[0].clientY - touchStart.y;
+ if (Math.abs(dx)+Math.abs(dy) < 24) return;
+ let nd;
+ if (Math.abs(dx) > Math.abs(dy)) nd = {x:dx>0?1:-1,y:0};
+ else nd = {x:0,y:dy>0?1:-1};
+ if (!(nd.x===-dir.x&&nd.y===-dir.y) && !(nd.x===dir.x&&nd.y===dir.y)) nextDir = nd;
+ touchStart = null;
+ }, {passive:true});
+
+ function showOverlay(title,text,btn){
+ el.ovTitle.textContent = title;
+ el.ovText.innerHTML = text;
+ el.startBtn.textContent = btn;
+ el.overlay.classList.remove('hide');
+ }
+ function hideOverlay(){ el.overlay.classList.add('hide'); }
+
+ function start() {
+ reset();
+ hideOverlay();
+ acc = 0;
+ state = 'playing';
+ }
+
+ el.startBtn.addEventListener('click', () => {
+ if (state === 'paused') { hideOverlay(); state='playing'; }
+ else start();
+ });
+
+ // boot
+ reset();
+ requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/dfaee602df0d/claude-code.png b/data/artifacts/dfaee602df0d/claude-code.png
new file mode 100644
index 0000000..492449d
Binary files /dev/null and b/data/artifacts/dfaee602df0d/claude-code.png differ
diff --git a/data/artifacts/dfaee602df0d/qwen25-7b.html b/data/artifacts/dfaee602df0d/qwen25-7b.html
new file mode 100644
index 0000000..f268e58
--- /dev/null
+++ b/data/artifacts/dfaee602df0d/qwen25-7b.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>AI Swarm Snake</title>
+ <style>
+ body { margin: 0; overflow: hidden; background: #0a192f; }
+ canvas { display: block; width: 100%; height: 100% }
+ .node, .task { fill: #67c23a; stroke: #fff; stroke-width: 1.5px; opacity: 0.8; transition: all 0.1s ease; }
+ .node:hover, .task:hover { opacity: 1; }
+ .game-over { position: absolute; top: 40%; left: 32%; width: 36%; text-align: center; font-family: sans-serif; color: #87ceeb; }
+ </style>
+</head>
+<body>
+<canvas id="gameCanvas"></canvas>
+<script>
+const canvas = document.getElementById('gameCanvas');
+const ctx = canvas.getContext('2d');
+canvas.width = 400;
+canvas.height = 400;
+
+let nodes = [{x:150, y:150}];
+let tasks = [];
+let score = 0;
+let dir = {x:0, y:0};
+let gameSpeed = 60;
+
+function drawNode(x, y) {
+ ctx.fillStyle = '#67c23a';
+ ctx.fillRect(x * 10 + 1, y * 10 + 1, 8, 8);
+}
+
+function drawTask(x, y) {
+ ctx.fillStyle = '#ff5722';
+ ctx.fillRect(x * 10 + 1, y * 10 + 1, 8, 8);
+}
+
+function update() {
+ if (!dir.x && !dir.y) return;
+ let headX = Math.floor((nodes[0].x += dir.x) / 10) % 40;
+ let headY = Math.floor((nodes[0].y += dir.y) / 10) % 40;
+
+ if (headX < 0 || headX >= 40 || headY < 0 || headY >= 40 || nodes.some(n => n.x === headX && n.y === headY)) {
+ alert('Game Over');
+ return;
+ }
+
+ let newNode = {x: headX, y: headY};
+ if (tasks.length > 0) {
+ tasks.forEach(task => task.active && (task.active = false));
+ while (nodes.some(n => n.x === newNode.x && n.y === newNode.y)) newNode = {x: Math.floor(Math.random() * 40), y: Math.floor(Math.random() * 40)};
+ nodes.unshift(newNode);
+ tasks.push({x:newNode.x, y:newNode.y, active:true});
+ score++;
+ } else {
+ nodes.unshift(newNode);
+ nodes.pop();
+ }
+}
+
+function draw() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ nodes.forEach(drawNode);
+ tasks.forEach((task) => task.active && drawTask(task.x, task.y));
+ document.title = `AI Swarm Snake | Score: ${score}`;
+}
+
+document.addEventListener('keydown', e => {
+ if (e.key === 'ArrowUp' || e.key === 'w') dir = {x:0, y:-1};
+ else if (e.key === 'ArrowDown' || e.key === 's') dir = {x:0, y:1};
+ else if (e.key === 'ArrowLeft' || e.key === 'a') dir = {x:-1, y:0};
+ else if (e.key === 'ArrowRight' || e.key === 'd') dir = {x:1, y:0};
+});
+
+setInterval(() => {
+ update();
+ draw();
+}, 1000 / gameSpeed);
+</script>
+<div class="game-over">Game Over. Score: <span id="score">0</span></div>
+<script>
+document.getElementById('score').innerText = score;
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/dfaee602df0d/qwen25-7b.png b/data/artifacts/dfaee602df0d/qwen25-7b.png
new file mode 100644
index 0000000..8980ea8
Binary files /dev/null and b/data/artifacts/dfaee602df0d/qwen25-7b.png differ
diff --git a/data/artifacts/ea271db82cff/qwen25-7b.html b/data/artifacts/ea271db82cff/qwen25-7b.html
new file mode 100644
index 0000000..589cf9a
--- /dev/null
+++ b/data/artifacts/ea271db82cff/qwen25-7b.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Metaball Field</title>
+<style>
+body { margin: 0; overflow: hidden; }
+canvas { display: block; background: #222; width: 100vw; height: 100vh; cursor: none; }
+#controls { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); }
+</style>
+</head>
+<body>
+<div id="controls">
+<label for="theme">Theme:</label>
+<select id="theme">
+<option value="classic">Classic</option>
+<option value="summer">Summer</option>
+<option value="winter">Winter</option>
+</select>
+<br><br>
+<label for="count">Blob Count:</label>
+<input type="range" min="10" max="50" step="1" id="count">
+<span id="countVal">25</span>
+</div>
+<canvas></canvas>
+<script>
+const canvas = document.querySelector('canvas');
+const ctx = canvas.getContext('2d');
+
+const THEMES = {
+ classic: { bg: ['#000', '#111'] },
+ summer: { bg: ['#fff', '#ff9'] },
+ winter: { bg: ['#0f0', '#0ff'] }
+};
+
+let theme = THEMES.classic;
+let count = 25;
+
+function buildRamp(theme) {
+ const ramp = new Uint8ClampedArray(768);
+ for (let i = 0; i < 256; i++) {
+ const p = i / 255;
+ let a = theme.bg[0], b = theme.bg[1];
+ if (p >= stops[0][0] && p <= stops[stops.length - 1][0]) { a = stops[0]; b = stops[stops.length - 1]; }
+ const span = (b[0] - a[0]) || 1;
+ const f = (p - a[0]) / span;
+ ramp[i * 3] = a[1] + (b[1] - a[1]) * f;
+ ramp[i * 3 + 1] = a[2] + (b[2] - a[2]) * f;
+ }
+}
+
+const stops = [[0, '#000'], [1, '#fff']];
+buildRamp(theme);
+
+let W = canvas.width = Math.max(1, window.innerWidth);
+let H = canvas.height = Math.max(1, window.innerHeight);
+let minDim = Math.min(W, H);
+let scale = 0.22;
+let imgData = null, buf = null;
+let bgGrad = ctx.createLinearGradient(0, 0, 0, H);
+bgGrad.addColorStop(0, theme.bg[0]);
+bgGrad.addColorStop(1, theme.bg[1]);
+
+function resize() {
+ W = canvas.width = Math.max(1, window.innerWidth);
+ H = canvas.height = Math.max(1, window.innerHeight);
+ minDim = Math.min(W, H);
+ scale = 0.26 < 200 / Math.max(W, H) ? 0.26 : 200 / Math.max(W, H);
+ lowW = Math.round(W * scale);
+ lowH = Math.round(H * scale);
+ imgData = offCtx.createImageData(lowW, lowH);
+ buf = imgData.data;
+ bgGrad = ctx.createLinearGradient(0, 0, 0, H);
+ bgGrad.addColorStop(0, theme.bg[0]);
+ bgGrad.addColorStop(1, theme.bg[1]);
+}
+
+function makeBlob() {
+ return { x: Math.random() * W, y: Math.random() * H, rFrac: 0.05 + Math.random() * 0.055, vs: 0.25 + Math.random() * 0.5, vp: Math.random() * Math.PI * 2, vamp: 45 + Math.random() * 70, hs: 0.15 + Math.random() * 0.35, hp: Math.random() * Math.PI * 2, hamp: 18 + Math.random() * 34, ps: 0.4 + Math.random() * 0.8, r: 40 };
+}
+
+function setCount(n) {
+ while (blobs.length < n) blobs.push(makeBlob());
+ while (blobs.length > n) blobs.pop();
+}
+
+const blobs = [];
+
+function recomputeRadius(b) {
+ b.r = b.rFrac * minDim;
+}
+
+function update(t, dt) {
+ for (const b of blobs) {
+ const vy = Math.sin(t * b.vs + b.vp) * b.vamp;
+ const vx = Math.sin(t * b.hs + b.hp) * b.hamp;
+ b.x += vx * dt;
+ b.y += vy * dt;
+
+ const pad = b.r * 0.35;
+ if (b.x < pad) { b.x = pad; b.hp += Math.PI; }
+ else if (b.x > W - pad) { b.x = W - pad; b.hp += Math.PI; }
+ if (b.y < pad) { b.y = pad; b.vp += Math.PI; }
+ else if (b.y > H - pad) { b.y = H - pad; b.vp += Math.PI; }
+
+ b.rr = b.r * (1 + Math.sin(t * b.ps + b.pp) * 0.14);
+ }
+}
+
+function renderField(t) {
+ const n = blobs.length;
+ const bx = new Float32Array(n), by = new Float32Array(n), br2 = new Float32Array(n);
+ for (let i = 0; i < n; i++) {
+ const b = blobs[i];
+ bx[i] = b.x * scale;
+ by[i] = b.y * scale;
+ const rl = b.rr * scale;
+ br2[i] = rl * rl;
+ }
+
+ let p = 0;
+ for (let y = 0; y < lowH; y++) {
+ for (let x = 0; x < lowW; x++) {
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ const dx = x - bx[i], dy = y - by[i];
+ const d2 = dx * dx + dy * dy + 0.0001;
+ sum += br2[i] / d2;
+ }
+ let a;
+ if (sum < 0.65) {
+ a = 0;
+ } else {
+ a = sum < 1.05 ? (sum - 0.65) / 0.4 : 1;
+ const ct = (sum - 0.7) / 2.6;
+ if (ct < 0) ct = 0; else if (ct > 1) ct = 1;
+ const ci = (ct * 255) | 0;
+ const r3 = ci * 3;
+ buf[p] = ramp[r3];
+ buf[p + 1] = ramp[r3 + 1];
+ buf[p + 2] = ramp[r3 + 2];
+ }
+ buf[p + 3] = a * 255;
+ p += 4;
+ }
+ }
+ offCtx.putImageData(imgData, 0, 0);
+}
+
+let last = performance.now();
+function frame(now) {
+ let dt = (now - last) / 1000;
+ if (dt > 0.05) dt = 0.05;
+ last = now;
+ const t = now / 1000;
+
+ update(t, dt);
+ renderField(t);
+
+ ctx.globalCompositeOperation = "source-over";
+ ctx.fillStyle = bgGrad;
+ ctx.fillRect(0, 0, W, H);
+ ctx.imageSmoothingEnabled = true;
+ ctx.imageSmoothingQuality = "high";
+ ctx.drawImage(off, 0, 0, lowW, lowH, 0, 0, W, H);
+ ctx.globalCompositeOperation = "lighter";
+ ctx.globalAlpha = 0.28;
+ ctx.drawImage(off, 0, 0, lowW, lowH, 0, 0, W, H);
+ ctx.globalAlpha = 1;
+ ctx.globalCompositeOperation = "source-over";
+
+ requestAnimationFrame(frame);
+}
+
+setCount(count);
+resize();
+requestAnimationFrame(frame);
+
+document.getElementById('theme').addEventListener('change', function() {
+ theme = THEMES[this.value] || THEMES.classic;
+ buildRamp(theme);
+ bgGrad = ctx.createLinearGradient(0, 0, 0, H);
+ bgGrad.addColorStop(0, theme.bg[0]);
+ bgGrad.addColorStop(1, theme.bg[1]);
+});
+
+document.getElementById('count').addEventListener('input', function() {
+ countVal.textContent = this.value;
+ setCount(parseInt(this.value, 10));
+});
+
+window.addEventListener('resize', resize);
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ea271db82cff/qwen25-7b.png b/data/artifacts/ea271db82cff/qwen25-7b.png
new file mode 100644
index 0000000..d8ea6f1
Binary files /dev/null and b/data/artifacts/ea271db82cff/qwen25-7b.png differ
diff --git a/data/artifacts/ea271db82cff/qwen3-14b.html b/data/artifacts/ea271db82cff/qwen3-14b.html
new file mode 100644
index 0000000..2f46210
--- /dev/null
+++ b/data/artifacts/ea271db82cff/qwen3-14b.html
@@ -0,0 +1,444 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Metaball Lava Lamp</title>
+<style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
+
+ #lamp {
+ display: block;
+ width: 100vw;
+ height: 100vh;
+ }
+
+ #panel {
+ position: fixed;
+ top: 18px;
+ left: 18px;
+ padding: 16px 18px 18px;
+ border-radius: 16px;
+ background: rgba(20, 12, 30, 0.42);
+ backdrop-filter: blur(14px) saturate(140%);
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
+ border: 1px solid rgba(255, 255, 255, 0.12);
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45);
+ color: #f4eef8;
+ width: 224px;
+ user-select: none;
+ z-index: 10;
+ transition: opacity 0.3s;
+ }
+
+ #panel h1 {
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: 1.6px;
+ text-transform: uppercase;
+ opacity: 0.85;
+ margin-bottom: 14px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ #panel h1 .dot {
+ width: 9px;
+ height: 9px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 30% 30%, #ffe066, #ff2d55);
+ box-shadow: 0 0 10px #ff5e3a;
+ }
+
+ .row {
+ margin-bottom: 14px;
+ }
+
+ .row:last-child {
+ margin-bottom: 0;
+ }
+
+ label {
+ display: block;
+ font-size: 11px;
+ letter-spacing: 0.5px;
+ opacity: 0.7;
+ margin-bottom: 7px;
+ display: flex;
+ justify-content: space-between;
+ }
+
+ label b {
+ opacity: 0.95;
+ font-weight: 600;
+ }
+
+ select {
+ width: 100%;
+ padding: 8px 10px;
+ border-radius: 9px;
+ background: rgba(255, 255, 255, 0.07);
+ color: #f4eef8;
+ border: 1px solid rgba(255, 255, 255, 0.14);
+ font-size: 13px;
+ outline: none;
+ cursor: pointer;
+ appearance: none;
+ -webkit-appearance: none;
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4l4 4 4-4' stroke='%23f4eef8' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ }
+
+ select option {
+ background: #1a1024;
+ color: #f4eef8;
+ }
+
+ input[type=range] {
+ width: 100%;
+ -webkit-appearance: none;
+ appearance: none;
+ height: 5px;
+ border-radius: 5px;
+ background: rgba(255, 255, 255, 0.18);
+ outline: none;
+ cursor: pointer;
+ }
+
+ input[type=range]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 17px;
+ height: 17px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 32% 30%, #ffe9a8, #ff7a00);
+ border: 2px solid rgba(255, 255, 255, 0.5);
+ box-shadow: 0 0 8px rgba(255, 120, 40, 0.7);
+ }
+
+ input[type=range]::-moz-range-thumb {
+ width: 15px;
+ height: 15px;
+ border-radius: 50%;
+ background: radial-gradient(circle at 32% 30%, #ffe9a8, #ff7a00);
+ border: 2px solid rgba(255, 255, 255, 0.5);
+ box-shadow: 0 0 8px rgba(255, 120, 40, 0.7);
+ }
+
+ #hint {
+ position: fixed;
+ bottom: 14px;
+ left: 0;
+ right: 0;
+ text-align: center;
+ color: rgba(255, 255, 255, 0.28);
+ font-size: 11px;
+ letter-spacing: 1px;
+ z-index: 5;
+ pointer-events: none;
+ }
+</style>
+</head>
+<body>
+<canvas id="lamp"></canvas>
+
+<div id="panel">
+ <h1><span class="dot"></span>Lava Lamp</h1>
+ <div class="row">
+ <label>Color Theme</label>
+ <select id="theme">
+ <option value="classic">Classic Lava</option>
+ <option value="ember">Ember Glow</option>
+ <option value="sunset">Sunset</option>
+ <option value="amethyst">Amethyst</option>
+ <option value="ocean">Deep Ocean</option>
+ <option value="toxic">Toxic</option>
+ </select>
+ </div>
+ <div class="row">
+ <label>Blobs <b id="countVal">12</b></label>
+ <input type="range" id="count" min="3" max="26" value="12">
+ </div>
+</div>
+
+<div id="hint">metaballs rise · fall · merge</div>
+
+<script>
+(function () {
+ "use strict";
+
+ const canvas = document.getElementById("lamp");
+ const ctx = canvas.getContext("2d");
+
+ const off = document.createElement("canvas");
+ const offCtx = off.getContext("2d");
+
+ // Themes with more refined gradients and color stops
+ const THEMES = {
+ classic: {
+ bg: ["#2a0a3a", "#160326"],
+ stops: [
+ [0, "#7a0f3a"],
+ [0.35, "#ff2d55"],
+ [0.7, "#ff8a00"],
+ [1, "#ffe066"]
+ ]
+ },
+ ember: {
+ bg: ["#220a05", "#120302"],
+ stops: [
+ [0, "#7a1500"],
+ [0.4, "#ff3d00"],
+ [0.72, "#ff7a00"],
+ [1, "#ffc46b"]
+ ]
+ },
+ sunset: {
+ bg: ["#1b1035", "#360d38"],
+ stops: [
+ [0, "#5b1250"],
+ [0.35, "#ff4d6d"],
+ [0.7, "#ff9e5e"],
+ [1, "#ffd76e"]
+ ]
+ },
+ amethyst: {
+ bg: ["#14052a", "#26063f"],
+ stops: [
+ [0, "#5a1a8a"],
+ [0.4, "#c04dff"],
+ [0.72, "#ff5edb"],
+ [1, "#ffd1f5"]
+ ]
+ },
+ ocean: {
+ bg: ["#041b2d", "#06263a"],
+ stops: [
+ [0, "#053a5c"],
+ [0.38, "#00c8ff"],
+ [0.72, "#2b8cff"],
+ [1, "#bfeaff"]
+ ]
+ },
+ toxic: {
+ bg: ["#071a07", "#0a250a"],
+ stops: [
+ [0, "#2c5c00"],
+ [0.4, "#7bd400"],
+ [0.72, "#39ff14"],
+ [1, "#eaffb0"]
+ ]
+ }
+ };
+
+ let theme = THEMES.classic;
+ let ramp = new Uint8Array(256 * 3);
+
+ function hexToRgb(h) {
+ h = h.replace("#", "");
+ return [
+ parseInt(h.slice(0, 2), 16),
+ parseInt(h.slice(2, 4), 16),
+ parseInt(h.slice(4, 6), 16)
+ ];
+ }
+
+ function buildRamp(t) {
+ const stops = t.stops;
+ for (let i = 0; i < 256; i++) {
+ const p = i / 255;
+ let a = stops[0], b = stops[stops.length - 1];
+ for (let s = 0; s < stops.length - 1; s++) {
+ if (p >= stops[s][0] && p <= stops[s + 1][0]) {
+ a = stops[s]; b = stops[s + 1]; break;
+ }
+ }
+ const span = (b[0] - a[0]) || 1;
+ const f = (p - a[0]) / span;
+ const ca = hexToRgb(a[1]), cb = hexToRgb(b[1]);
+ ramp[i * 3] = ca[0] + (cb[0] - ca[0]) * f;
+ ramp[i * 3 + 1] = ca[1] + (cb[1] - ca[1]) * f;
+ ramp[i * 3 + 2] = ca[2] + (cb[2] - ca[2]) * f;
+ }
+ }
+
+ buildRamp(theme);
+
+ let W = 0, H = 0, minDim = 0;
+ let lowW = 0, lowH = 0, scale = 0.22;
+ let imgData = null, buf = null;
+ let bgGrad = null;
+
+ function resize() {
+ W = canvas.width = Math.max(1, window.innerWidth);
+ H = canvas.height = Math.max(1, window.innerHeight);
+ minDim = Math.min(W, H);
+
+ scale = Math.min(0.26, 200 / Math.max(W, H));
+ lowW = Math.max(2, Math.round(W * scale));
+ lowH = Math.max(2, Math.round(H * scale));
+ off.width = lowW;
+ off.height = lowH;
+ imgData = offCtx.createImageData(lowW, lowH);
+ buf = imgData.data;
+
+ bgGrad = ctx.createLinearGradient(0, 0, 0, H);
+ bgGrad.addColorStop(0, theme.bg[0]);
+ bgGrad.addColorStop(1, theme.bg[1]);
+
+ for (const b of blobs) recomputeRadius(b);
+ }
+
+ const blobs = [];
+
+ function recomputeRadius(b) {
+ b.r = b.rFrac * minDim;
+ }
+
+ function makeBlob() {
+ const b = {
+ x: Math.random() * (W || 800),
+ y: Math.random() * (H || 600),
+ rFrac: 0.05 + Math.random() * 0.055,
+ vs: 0.25 + Math.random() * 0.5, // vertical osc speed
+ vp: Math.random() * Math.PI * 2, // vertical phase
+ vamp: 45 + Math.random() * 70, // vertical amplitude (px/s)
+ hs: 0.15 + Math.random() * 0.35, // horizontal speed
+ hp: Math.random() * Math.PI * 2,
+ hamp: 18 + Math.random() * 34, // horizontal drift
+ ps: 0.4 + Math.random() * 0.8, // pulse speed
+ pp: Math.random() * Math.PI * 2,
+ r: 40
+ };
+ recomputeRadius(b);
+ return b;
+ }
+
+ function setCount(n) {
+ while (blobs.length < n) blobs.push(makeBlob());
+ while (blobs.length > n) blobs.pop();
+ }
+
+ function update(t, dt) {
+ for (const b of blobs) {
+ const vy = Math.sin(t * b.vs + b.vp) * b.vamp;
+ const vx = Math.sin(t * b.hs + b.hp) * b.hamp;
+ b.x += vx * dt;
+ b.y += vy * dt;
+
+ const pad = b.r * 0.35;
+ if (b.x < pad) {
+ b.x = pad;
+ b.hp += Math.PI;
+ } else if (b.x > W - pad) {
+ b.x = W - pad;
+ b.hp += Math.PI;
+ }
+ if (b.y < pad) {
+ b.y = pad;
+ b.vp += Math.PI;
+ } else if (b.y > H - pad) {
+ b.y = H - pad;
+ b.vp += Math.PI;
+ }
+
+ b.rr = b.r * (1 + Math.sin(t * b.ps + b.pp) * 0.14); // pulsating radius
+ }
+ }
+
+ function renderField(t) {
+ const n = blobs.length;
+ const bx = new Float32Array(n), by = new Float32Array(n), br2 = new Float32Array(n);
+ for (let i = 0; i < n; i++) {
+ const b = blobs[i];
+ bx[i] = b.x * scale;
+ by[i] = b.y * scale;
+ const rl = b.rr * scale;
+ br2[i] = rl * rl;
+ }
+
+ let p = 0;
+ for (let y = 0; y < lowH; y++) {
+ for (let x = 0; x < lowW; x++) {
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ const dx = x - bx[i], dy = y - by[i];
+ const d2 = dx * dx + dy * dy + 0.0001;
+ sum += br2[i] / d2;
+ }
+ let a;
+ if (sum < 0.65) {
+ a = 0;
+ } else {
+ a = sum < 1.05 ? (sum - 0.65) / 0.4 : 1;
+ let ct = (sum - 0.7) / 2.6; // color param edge->core
+ if (ct < 0) ct = 0; else if (ct > 1) ct = 1;
+ const ci = (ct * 255) | 0;
+ const r3 = ci * 3;
+ buf[p] = ramp[r3];
+ buf[p + 1] = ramp[r3 + 1];
+ buf[p + 2] = ramp[r3 + 2];
+ }
+ buf[p + 3] = a * 255;
+ p += 4;
+ }
+ }
+ offCtx.putImageData(imgData, 0, 0);
+ }
+
+ let last = performance.now();
+ function frame(now) {
+ let dt = (now - last) / 1000;
+ if (dt > 0.05) dt = 0.05;
+ last = now;
+ const t = now / 1000;
+
+ update(t, dt);
+ renderField(t);
+
+ ctx.globalCompositeOperation = "source-over";
+ ctx.fillStyle = bgGrad;
+ ctx.fillRect(0, 0, W, H);
+
+ ctx.imageSmoothingEnabled = true;
+ ctx.imageSmoothingQuality = "high";
+ ctx.drawImage(off, 0, 0, lowW, lowH, 0, 0, W, H);
+
+ ctx.globalCompositeOperation = "lighter";
+ ctx.globalAlpha = 0.28;
+ ctx.drawImage(off, 0, 0, lowW, lowH, 0, 0, W, H);
+ ctx.globalAlpha = 1;
+ ctx.globalCompositeOperation = "source-over";
+
+ requestAnimationFrame(frame);
+ }
+
+ const themeSel = document.getElementById("theme");
+ const countInp = document.getElementById("count");
+ const countVal = document.getElementById("countVal");
+
+ themeSel.addEventListener("change", function () {
+ theme = THEMES[themeSel.value] || THEMES.classic;
+ buildRamp(theme);
+ bgGrad = ctx.createLinearGradient(0, 0, 0, H);
+ bgGrad.addColorStop(0, theme.bg[0]);
+ bgGrad.addColorStop(1, theme.bg[1]);
+ });
+
+ countInp.addEventListener("input", function () {
+ countVal.textContent = countInp.value;
+ setCount(parseInt(countInp.value, 10));
+ });
+
+ window.addEventListener("resize", resize);
+
+ setCount(parseInt(countInp.value, 10));
+ resize();
+ requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/data/artifacts/ea271db82cff/qwen3-14b.png b/data/artifacts/ea271db82cff/qwen3-14b.png
new file mode 100644
index 0000000..ed7d3e7
Binary files /dev/null and b/data/artifacts/ea271db82cff/qwen3-14b.png differ
diff --git a/data/challenges.json b/data/challenges.json
index cc7e775..7ac2bba 100644
--- a/data/challenges.json
+++ b/data/challenges.json
@@ -11411,22 +11411,24 @@
"runs": [
{
"model": "qwen3-14b",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": 0,
- "cost": null,
+ "seconds": 95,
+ "cost": 0,
"started_at": "2026-07-25T06:17:53.534Z",
- "finished_at": null,
+ "finished_at": "2026-07-25T06:19:28.457Z",
"queued_at": "2026-07-25T06:17:53.526Z",
- "resumes": 1
+ "resumes": 1,
+ "bytes": 11236,
+ "thumb": true
},
{
"model": "gemma3-12b",
- "status": "queued",
+ "status": "running",
"error": null,
"seconds": 0,
"cost": null,
- "started_at": null,
+ "started_at": "2026-07-25T06:19:28.462Z",
"finished_at": null,
"queued_at": "2026-07-25T06:17:53.528Z",
"resumes": 1
@@ -11444,14 +11446,16 @@
},
{
"model": "qwen25-7b",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": 0,
- "cost": null,
+ "seconds": 52,
+ "cost": 0,
"started_at": "2026-07-25T06:17:53.541Z",
- "finished_at": null,
+ "finished_at": "2026-07-25T06:18:45.048Z",
"queued_at": "2026-07-25T06:17:53.531Z",
- "resumes": 1
+ "resumes": 1,
+ "bytes": 6014,
+ "thumb": true
},
{
"model": "hf-qwen-coder-32b",
@@ -11509,13 +11513,15 @@
},
{
"model": "qwen25-7b",
- "status": "queued",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
- "started_at": null,
- "finished_at": null,
- "queued_at": "2026-07-25T06:18:24.462Z"
+ "seconds": 23,
+ "cost": 0,
+ "started_at": "2026-07-25T06:18:45.053Z",
+ "finished_at": "2026-07-25T06:19:07.734Z",
+ "queued_at": "2026-07-25T06:18:24.462Z",
+ "bytes": 2758,
+ "thumb": true
},
{
"model": "hf-qwen-coder-32b",
@@ -11529,13 +11535,14 @@
},
{
"model": "claude-code",
- "status": "running",
+ "status": "done",
"error": null,
- "seconds": null,
- "cost": null,
+ "seconds": 80,
+ "cost": 0,
"started_at": "2026-07-25T06:18:24.466Z",
- "finished_at": null,
- "queued_at": "2026-07-25T06:18:24.465Z"
+ "finished_at": "2026-07-25T06:19:44.371Z",
+ "queued_at": "2026-07-25T06:18:24.465Z",
+ "bytes": 15575
}
]
}
diff --git a/data/landings/10c3c876aa67-grok.html b/data/landings/10c3c876aa67-grok.html
new file mode 100644
index 0000000..4ca21b6
--- /dev/null
+++ b/data/landings/10c3c876aa67-grok.html
@@ -0,0 +1,222 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Living Fractal Tree — built by Grok 4.5 · Model Arena</title>
+<style>*{box-sizing:border-box}html,body{margin:0;height:100%;background:#0b0d10;color:#e6ecf2;font:14px/1.5 ui-monospace,Menlo,monospace}
+header{display:flex;align-items:center;gap:14px;padding:13px 20px;border-bottom:1px solid #1c2430;background:#0e1116}
+header .k{color:#7cf;font-weight:700;letter-spacing:2px;text-transform:uppercase;font-size:12px;white-space:nowrap}
+header h1{font-size:15px;margin:0;font-weight:600}header .by{color:#8a93a0;font-size:12px;margin-left:auto;white-space:nowrap}
+.wrap{height:calc(100% - 51px)}iframe{width:100%;height:100%;border:0;background:#000;display:block}</style></head><body>
+<header><span class="k">⚔ Model Arena</span><h1>Living Fractal Tree</h1><span class="by">built by <b>Grok 4.5</b></span></header>
+<div class="wrap"><iframe sandbox="allow-scripts allow-pointer-lock" srcdoc="<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Fractal Tree</title>
+<style>
+*{margin:0;padding:0;box-sizing:border-box}
+body{overflow:hidden;background:#0a0a12;font-family:system-ui,sans-serif}
+canvas{display:block;width:100vw;height:100vh}
+.ui{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:rgba(20,20,35,0.85);backdrop-filter:blur(12px);padding:14px 28px;border-radius:16px;border:1px solid rgba(255,255,255,0.08);display:flex;align-items:center;gap:16px;z-index:10;box-shadow:0 8px 32px rgba(0,0,0,0.4)}
+.ui label{color:#c8c8d8;font-size:13px;white-space:nowrap;letter-spacing:0.03em}
+.ui input[type=range]{width:160px;accent-color:#7cb87c;cursor:pointer}
+.ui span{color:#8fbc8f;font-size:13px;font-variant-numeric:tabular-nums;min-width:18px}
+</style>
+</head>
+<body>
+<canvas id="c"></canvas>
+<div class="ui">
+<label>Branch Depth</label>
+<input type="range" id="depth" min="1" max="12" value="9" step="1">
+<span id="dval">9</span>
+</div>
+<script>
+const canvas=document.getElementById('c');
+const ctx=canvas.getContext('2d');
+const depthSlider=document.getElementById('depth');
+const dval=document.getElementById('dval');
+
+let W,H,maxDepth=9,time=0,growProgress=0;
+const leaves=[];
+const falling=[];
+const SEASON_COLORS=[
+ ['#2d5a27','#3d7a37','#4a8f3f','#5ba84a'],
+ ['#c45c26','#d4763a','#e8a04a','#b84020','#8b4513','#cd853f'],
+ ['#e8e8f0','#d0d0e0','#c0c8d8','#a8b0c0'],
+ ['#3a7a30','#4a9a3a','#5cb84a','#2d6a28','#6bc45a']
+];
+let season=0;
+let seasonTimer=0;
+
+function resize(){
+ W=canvas.width=window.innerWidth;
+ H=canvas.height=window.innerHeight;
+}
+window.addEventListener('resize',resize);
+resize();
+
+depthSlider.addEventListener('input',()=>{
+ maxDepth=+depthSlider.value;
+ dval.textContent=maxDepth;
+ growProgress=0;
+ leaves.length=0;
+ falling.length=0;
+});
+
+function wind(y,t){
+ return Math.sin(t*0.7+y*0.008)*0.12+Math.sin(t*1.3+y*0.015)*0.06+Math.sin(t*0.3)*0.04;
+}
+
+function drawBranch(x,y,len,angle,depth,t){
+ if(depth>maxDepth||len<2)return;
+ const grow=Math.min(1,Math.max(0,(growProgress-depth*0.08)/(0.5)));
+ if(grow<=0)return;
+ const w=wind(y,t)*(1+depth*0.15);
+ const a=angle+w;
+ const el=len*grow;
+ const x2=x+Math.sin(a)*el;
+ const y2=y-Math.cos(a)*el;
+
+ const trunk=depth===0;
+ const lw=Math.max(0.5, (maxDepth-depth+1)*1.6*grow);
+ const tcol=Math.floor(40+depth*8);
+ ctx.beginPath();
+ ctx.moveTo(x,y);
+ ctx.lineTo(x2,y2);
+ ctx.strokeStyle=trunk?`rgb(${90+tcol*0.3},${60+tcol*0.2},${30})`:`rgb(${70+tcol},${50+tcol*0.6},${25+depth*2})`;
+ ctx.lineWidth=lw;
+ ctx.lineCap='round';
+ ctx.stroke();
+
+ if(depth>=maxDepth-3&&grow>0.7){
+ const cols=SEASON_COLORS[season%4];
+ const n=depth===maxDepth?3:1;
+ for(let i=0;i<n;i++){
+ const lx=x2+(Math.random()-0.5)*8;
+ const ly=y2+(Math.random()-0.5)*8;
+ const col=cols[Math.floor(Math.random()*cols.length)];
+ const r=2+Math.random()*3;
+ leaves.push({x:lx,y:ly,r,col,ox:lx,oy:ly,phase:Math.random()*Math.PI*2,depth});
+ if(leaves.length>800)leaves.shift();
+ }
+ }
+
+ const shrink=0.68+Math.sin(depth+t*0.1)*0.04;
+ const spread=0.45+Math.sin(depth*1.3)*0.08;
+ drawBranch(x2,y2,len*shrink,a-spread,depth+1,t);
+ drawBranch(x2,y2,len*shrink,a+spread,depth+1,t);
+ if(depth>2&&depth<maxDepth-1&&Math.sin(depth*7.3)>0.3){
+ drawBranch(x2,y2,len*shrink*0.75,a+spread*0.3*(depth%2?1:-1),depth+1,t);
+ }
+}
+
+function spawnFalling(){
+ if(leaves.length===0)return;
+ if(Math.random()>0.15)return;
+ const src=leaves[Math.floor(Math.random()*leaves.length)];
+ const cols=SEASON_COLORS[season%4];
+ falling.push({
+ x:src.x,y:src.y,
+ vx:(Math.random()-0.5)*1.2,
+ vy:0.3+Math.random()*0.6,
+ r:src.r*(0.7+Math.random()*0.5),
+ col:cols[Math.floor(Math.random()*cols.length)],
+ rot:Math.random()*Math.PI*2,
+ rv:(Math.random()-0.5)*0.08,
+ life:1
+ });
+ if(falling.length>300)falling.shift();
+}
+
+function updateFalling(t){
+ for(let i=falling.length-1;i>=0;i--){
+ const p=falling[i];
+ const w=wind(p.y,t)*40;
+ p.vx+=w*0.02;
+ p.vx*=0.98;
+ p.vy+=0.015;
+ p.x+=p.vx+Math.sin(t*2+p.rot)*0.4;
+ p.y+=p.vy;
+ p.rot+=p.rv;
+ p.life-=0.002;
+ if(p.y>H+20||p.life<=0)falling.splice(i,1);
+ }
+}
+
+function drawLeaves(t){
+ for(const l of leaves){
+ const w=wind(l.y,t);
+ const sx=l.ox+Math.sin(t*1.5+l.phase)*3+w*20;
+ const sy=l.oy+Math.cos(t*1.2+l.phase)*2;
+ l.x=sx;l.y=sy;
+ ctx.beginPath();
+ ctx.arc(sx,sy,l.r,0,Math.PI*2);
+ ctx.fillStyle=l.col;
+ ctx.globalAlpha=0.75;
+ ctx.fill();
+ }
+ ctx.globalAlpha=1;
+}
+
+function drawFalling(){
+ for(const p of falling){
+ ctx.save();
+ ctx.translate(p.x,p.y);
+ ctx.rotate(p.rot);
+ ctx.globalAlpha=Math.min(1,p.life)*0.85;
+ ctx.fillStyle=p.col;
+ ctx.beginPath();
+ ctx.ellipse(0,0,p.r,p.r*0.6,0,0,Math.PI*2);
+ ctx.fill();
+ ctx.restore();
+ }
+ ctx.globalAlpha=1;
+}
+
+function drawGround(){
+ const grd=ctx.createLinearGradient(0,H*0.85,0,H);
+ grd.addColorStop(0,'rgba(20,40,20,0)');
+ grd.addColorStop(0.3,'rgba(25,50,25,0.4)');
+ grd.addColorStop(1,'rgba(15,35,15,0.7)');
+ ctx.fillStyle=grd;
+ ctx.fillRect(0,H*0.85,W,H*0.15);
+}
+
+function drawSky(){
+ const grd=ctx.createLinearGradient(0,0,0,H);
+ const s=season%4;
+ if(s===0){grd.addColorStop(0,'#0c1a10');grd.addColorStop(1,'#1a2a18');}
+ else if(s===1){grd.addColorStop(0,'#1a1008');grd.addColorStop(1,'#2a1a10');}
+ else if(s===2){grd.addColorStop(0,'#0a0e18');grd.addColorStop(1,'#121828');}
+ else{grd.addColorStop(0,'#0a1810');grd.addColorStop(1,'#142818');}
+ ctx.fillStyle=grd;
+ ctx.fillRect(0,0,W,H);
+}
+
+function frame(ts){
+ time=ts*0.001;
+ growProgress=Math.min(1.5,growProgress+0.006);
+ seasonTimer+=0.001;
+ if(seasonTimer>12){seasonTimer=0;season++;leaves.length=0;}
+
+ drawSky();
+ drawGround();
+
+ const baseX=W/2;
+ const baseY=H*0.88;
+ const trunkLen=Math.min(W,H)*0.18;
+
+ leaves.length=0;
+ drawBranch(baseX,baseY,trunkLen,0,0,time);
+ drawLeaves(time);
+
+ spawnFalling();
+ updateFalling(time);
+ drawFalling();
+
+ requestAnimationFrame(frame);
+}
+requestAnimationFrame(frame);
+</script>
+</body>
+</html>" title="Living Fractal Tree"></iframe></div>
+</body></html>
\ No newline at end of file
diff --git a/idea-run/night-cycle.sh b/idea-run/night-cycle.sh
new file mode 100755
index 0000000..ee6070d
--- /dev/null
+++ b/idea-run/night-cycle.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+# night-cycle.sh — one iteration of the all-night DW/Agent-Abrams challenge loop.
+# 1. AI-judge any settled-but-unjudged battle (crowns it → surfaces in Arcade)
+# 2. fire the next idea ONLY if the Ollama backlog is small (self-limiting)
+# 3. commit new data
+# All $0 (local + claude-code Max plan). Prints a one-line status.
+set -uo pipefail
+ROOT="$HOME/Projects/model-arena"; cd "$ROOT"
+A="admin:DW2024!"; BASE="http://127.0.0.1:9758"
+
+# how many challenges still have running/queued runs?
+ACTIVE=$(curl -s -m 10 -u "$A" "$BASE/api/challenges" \
+ | python3 -c "import json,sys
+try: d=json.load(sys.stdin)
+except: print(0); sys.exit()
+ch=d if isinstance(d,list) else d.get('challenges',[])
+n=sum(1 for c in ch if any(r.get('status') in ('running','queued') for r in c.get('runs',[])))
+print(n)" 2>/dev/null || echo 0)
+
+# judge the most-recent settled Games/Real-Work battle that has thumbs but no aiPick
+JUDGED=$(curl -s -m 10 -u "$A" "$BASE/api/challenges" \
+ | python3 -c "import json,sys
+try: d=json.load(sys.stdin)
+except: sys.exit()
+ch=d if isinstance(d,list) else d.get('challenges',[])
+ch=[c for c in ch if not any(r.get('status') in ('running','queued') for r in c.get('runs',[]))]
+for c in ch:
+ if c.get('aiPick'): continue
+ if any(r.get('status')=='done' and r.get('thumb') for r in c.get('runs',[])):
+ print(c['id']); break" 2>/dev/null)
+if [ -n "${JUDGED:-}" ]; then
+ curl -s -m 90 -u "$A" -X POST "$BASE/api/challenges/$JUDGED/judge" >/dev/null 2>&1
+fi
+
+FIRED="(backlog $ACTIVE — skipped fire)"
+if [ "${ACTIVE:-0}" -le 1 ]; then
+ FIRED=$(bash "$ROOT/idea-run/run-next.sh" 2>&1 | tail -1)
+fi
+
+git add -A >/dev/null 2>&1
+git commit -q -m "night-loop: cycle $(date '+%H:%M') — judged=${JUDGED:-none} · $FIRED" >/dev/null 2>&1 && C="committed" || C="nothing to commit"
+GAMES=$(curl -s -m 8 -u "$A" "$BASE/api/arcade" | python3 -c "import json,sys;print(json.load(sys.stdin)['count'])" 2>/dev/null || echo '?')
+echo "CYCLE $(date '+%H:%M') | active=$ACTIVE | judged=${JUDGED:-none} | $FIRED | arcade=$GAMES games | $C"
← 0e921bc Add Games Arcade: /arcade gallery + /api/arcade auto-discove
·
back to Model Arena
·
auto-save: 2026-07-24T23:30:18 (21 files) — data/challenges. 3d2d7af →