| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>hyprbench β leaderboard</title> |
| <style> |
| :root { |
| --night: #0a0f14; --glow: #8ef0d2; --shimmer: #b3a6f0; --fog: #ccdfdb; |
| --dim: #5f7370; --line: #1b2733; |
| } |
| * { box-sizing: border-box; margin: 0; } |
| body { |
| background: var(--night); color: var(--fog); |
| font: 15px/1.6 "JetBrains Mono", ui-monospace, monospace; |
| max-width: 1100px; margin: 0 auto; padding: 48px 24px; |
| } |
| h1 { color: var(--glow); font-size: 28px; letter-spacing: 0.04em; } |
| h1::before { content: "β "; color: var(--shimmer); } |
| .sub { color: var(--dim); margin: 6px 0 36px; } |
| .sub a { color: var(--shimmer); text-decoration: none; } |
| table { width: 100%; border-collapse: collapse; margin: 18px 0 8px; } |
| th { |
| text-align: left; color: var(--shimmer); font-weight: 600; |
| border-bottom: 1px solid var(--line); padding: 8px 10px; white-space: nowrap; |
| } |
| td { padding: 9px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; } |
| tr:hover td { background: #0e151c; } |
| .rate { color: var(--glow); font-weight: 700; } |
| .bar { |
| display: inline-block; height: 8px; background: linear-gradient(90deg, var(--glow), var(--shimmer)); |
| border-radius: 4px; margin-right: 8px; vertical-align: middle; opacity: .85; |
| } |
| .lat { color: var(--fog); } .dim { color: var(--dim); font-size: 13px; } |
| .note { color: var(--dim); font-size: 13px; max-width: 980px; margin-top: 26px; } |
| .stamp { margin-top: 40px; color: var(--dim); font-size: 12.5px; border-top: 1px solid var(--line); padding-top: 14px; } |
| .stamp b { color: var(--glow); font-weight: 600; } |
| </style> |
| </head> |
| <body> |
| <h1>hyprbench</h1> |
| <p class="sub"> |
| a computer-use benchmark for <a href="https://hypr.land">Hyprland</a> β |
| real window-manager, browser, app, and system tasks; every verifier reads |
| state, never pixels. correctness <em>and</em> end-to-end latency. |
| <a href="https://github.com/crispwisp/hyprbench">source & tasks</a> |
| </p> |
| <table id="board"> |
| <thead><tr> |
| <th>agent</th><th>model</th><th>track</th><th>pass</th><th>rate</th> |
| <th>median</th><th>p90</th><th>max</th><th>total</th><th>run</th> |
| </tr></thead> |
| <tbody></tbody> |
| </table> |
| <p class="note" id="notes"></p> |
| <p class="stamp" id="stamp"></p> |
| <script> |
| fetch('results.json?t=' + Date.now()).then(r => r.json()).then(d => { |
| const tb = document.querySelector('#board tbody'); |
| d.runs.sort((a, b) => b.pass_rate - a.pass_rate || a.latency.median - b.latency.median); |
| for (const r of d.runs) { |
| const tr = document.createElement('tr'); |
| tr.innerHTML = ` |
| <td>${r.harness} <span class="dim">${r.harness_version || ''}</span></td> |
| <td>${r.model}</td> |
| <td>${r.track}</td> |
| <td>${r.passed}/${r.scored}</td> |
| <td><span class="bar" style="width:${r.pass_rate * 0.9}px"></span><span class="rate">${r.pass_rate}%</span></td> |
| <td class="lat">${r.latency.median}s</td> |
| <td class="lat">${r.latency.p90}s</td> |
| <td class="lat">${r.latency.max}s</td> |
| <td class="lat">${Math.round(r.latency.total / 60)}m</td> |
| <td class="dim">${r.commit} Β· ${r.date}</td>`; |
| tb.appendChild(tr); |
| } |
| const notes = d.runs.filter(r => r.note).map(r => `${r.label}: ${r.note}`); |
| document.getElementById('notes').textContent = notes.join(' β '); |
| document.getElementById('stamp').innerHTML = |
| `suite: <b>${d.suite.tasks} tasks</b> / ${d.suite.categories} categories Β· ` + |
| `modes: nested + host Β· oracle/noop validated both directions Β· ` + |
| `updated <b>${d.updated}</b> Β· results pushed live by <b>wisp</b> π²`; |
| }); |
| </script> |
|
|
| <h2 style="color:var(--glow);margin-top:48px;font-size:20px">β task samples</h2> |
| <p class="sub" style="margin-bottom:18px"> |
| oracle (reference-solution) runs recorded inside the sandboxed nested |
| compositor β exactly the desktop an agent sees and acts on. |
| </p> |
| <div id="demos" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:22px"></div> |
| <script> |
| const DEMOS = [ |
| { f: 'videos/wo-triangle.mp4', |
| t: 'wo-triangle β arrange three windows in a triangle', |
| d: 'The agent gets three windows in a flat row and the instruction to form a triangle: one centered on top, two below. The verifier does geometry over the compositor\'s own client state β apex above bases, bases split left/right β never pixels.' }, |
| { f: 'videos/wo-grid-3x3.mp4', |
| t: 'wo-grid-3x3 β nine windows into a 3Γ3 grid', |
| d: 'Nine floating windows must end up as a clean 3Γ3 grid. The predicate checks rows/columns against the windows\' bounding box with minimum-extent guards, so stacking everything on one point (a real hole we caught) cannot pass.' }, |
| { f: 'videos/cv-drag-slider.mp4', |
| t: 'cv-drag-slider β canvas pointer skill', |
| d: 'A slider drawn on a 2d canvas: no DOM inside, nothing to query β the goal value is only visible as pixels, so the agent must look and drag. The page records ground truth; the verifier reads it over the DevTools protocol with a stated tolerance.' }, |
| { f: 'videos/cv-connect-dots.mp4', |
| t: 'cv-connect-dots β one continuous stroke', |
| d: 'Press inside dot A, drag, release inside dot B. Separate clicks on each dot fail by design β the fixture distinguishes a sustained drag from clicking, which separates real pointer control from event spamming.' }, |
| ]; |
| const grid = document.getElementById('demos'); |
| for (const x of DEMOS) { |
| const c = document.createElement('div'); |
| c.innerHTML = `<video src="${x.f}" muted loop autoplay playsinline |
| style="width:100%;border:1px solid var(--line);border-radius:8px" onerror="this.closest('div').style.display='none'"></video> |
| <div style="color:var(--shimmer);font-weight:600;margin:8px 0 4px">${x.t}</div> |
| <div class="dim" style="white-space:normal">${x.d}</div>`; |
| grid.appendChild(c); |
| } |
| </script> |
| </body> |
| </html> |
|
|