Download app/tests/runtime-meter.mjs from Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP: direct link, hf CLI and curl.
- Browser
- Download file 7.85 kB
-
https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/runtime-meter.mjs
- Command line
-
hf download hf://spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/app/tests/runtime-meter.mjs
-
curl -L -o runtime-meter.mjs https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/runtime-meter.mjs
7.85 kB
| import { chromium } from 'playwright'; | |
| import fs from 'node:fs/promises'; | |
| import assert from 'node:assert/strict'; | |
| const url = process.argv[2] ?? 'http://127.0.0.1:4173/?source=local'; | |
| const label = process.argv[3] ?? 'agent-runtime-meter'; | |
| const result = { date: new Date().toISOString(), url, checks: [], layouts: [], errors: [] }; | |
| const browser = await chromium.launch({ executablePath: '/usr/bin/chromium', headless: true }); | |
| let context, page; | |
| try { | |
| for (const [width, height] of [[1440,1000],[1100,800],[1000,800],[851,800],[850,800],[390,844],[320,568],[390,420]]) { | |
| const page = await browser.newPage({ viewport: { width, height }, hasTouch: width < 500, deviceScaleFactor: 2 }); | |
| page.on('pageerror', e => result.errors.push(e.message)); | |
| await page.goto(url); await page.waitForFunction(() => window.browserPi?.runtimeMeter); await page.evaluate(() => window.browserPi.ready); | |
| assert.equal(await page.locator('.runtime-engine').innerText(), 'WebGPU'); | |
| assert.equal(await page.locator('.runtime-value').innerText(), 'Idle'); | |
| for (const event of [ | |
| { type: 'busy', action: 'load', cachedOnly: true }, | |
| { type: 'load_progress', phase: 'download', loaded: 184, total: 1840 }, | |
| { type: 'inference_activity', phase: 'prefill' }, | |
| ...[18,28,23,36,30,38,32].map(rate => ({ type: 'inference_activity', phase: 'decode', rate })), | |
| ]) await page.evaluate(event => window.browserPi.runtimeMeter.update(event), event); | |
| assert.equal(await page.locator('.runtime-value').textContent(), '32 tok/s'); | |
| assert(await page.locator('.runtime-sparkline').isVisible()); | |
| await page.waitForFunction(() => { | |
| const meter = document.querySelector('#runtime-meter'); | |
| const content = meter.querySelector('.runtime-content'); | |
| return Math.abs(meter.getBoundingClientRect().width - Math.ceil(content.getBoundingClientRect().width) - 2 * parseFloat(getComputedStyle(meter).paddingLeft)) < 1; | |
| }); | |
| const layout = await page.evaluate(() => { | |
| const rect = selector => { const r=document.querySelector(selector).getBoundingClientRect();return {x:r.x,y:r.y,right:r.right,bottom:r.bottom,width:r.width,height:r.height}; }; | |
| return { header:rect('header'), brand:rect('.brand'), meter:rect('#runtime-meter'), model:rect('.model-panel'), value:rect('.runtime-value'), overflow:document.documentElement.scrollWidth>innerWidth }; | |
| }); | |
| for (const item of [layout.brand,layout.meter,layout.model]) assert(item.x>=layout.header.x&&item.right<=layout.header.right&&item.y>=layout.header.y&&item.bottom<=layout.header.bottom,JSON.stringify({width,...layout})); | |
| assert(layout.brand.right<=layout.meter.x); | |
| assert(layout.value.right<=layout.meter.right-8); | |
| if(width>850)assert(layout.meter.right<=layout.model.x); | |
| assert(!layout.overflow); result.layouts.push({width,height,...layout}); | |
| await page.locator('header').screenshot({path:`../validation/${label}-fixture-${width}x${height}.png`}); | |
| await page.evaluate(()=>window.browserPi.runtimeMeter.update({type:'agent_event',event:{type:'tool_execution_start',toolName:'bash'}})); | |
| assert.equal(await page.locator('.runtime-value').textContent(),'Running bash…'); assert(!await page.locator('.runtime-sparkline').isVisible()); | |
| assert.equal(await page.locator('.runtime-engine').textContent(),'JavaScript'); | |
| await page.evaluate(()=>window.browserPi.runtimeMeter.update({type:'idle'})); | |
| assert.equal(await page.locator('.runtime-value').textContent(),'Idle'); | |
| assert.equal(await page.locator('.runtime-engine').textContent(),'WebGPU'); | |
| await page.evaluate(()=>window.browserPi.runtimeMeter.update({type:'inference_activity',phase:'decode',rate:32})); | |
| await page.waitForFunction(()=>document.querySelector('.runtime-value').textContent==='Generating…'); | |
| assert(!await page.locator('.runtime-sparkline').isVisible()); | |
| await page.close(); | |
| } | |
| result.checks.push('Eight viewport fixtures fit the header; measured bars, tool/idle states and stale-sample handling render correctly'); | |
| await browser.close(); | |
| context=await chromium.launchPersistentContext(new URL('../../validation/agent-browser-profile',import.meta.url).pathname,{ | |
| executablePath:'/usr/bin/chromium',headless:true,viewport:{width:1440,height:1000}, | |
| args:['--enable-unsafe-webgpu','--use-angle=vulkan','--enable-features=Vulkan','--disable-vulkan-surface'], | |
| }); | |
| context.setDefaultTimeout(180_000); page=await context.newPage(); page.on('pageerror',e=>result.errors.push(e.message)); | |
| await page.goto(url); await page.waitForFunction(()=>window.browserPi?.runtimeMeter); await page.evaluate(()=>window.browserPi.ready); | |
| await page.evaluate(()=>document.querySelector('#new-chat').onclick()); | |
| const nonce='METER-'+crypto.randomUUID().slice(0,8); | |
| await page.evaluate(nonce=>window.browserPi.rpc('write',{path:'/workspace/meter-check.txt',content:nonce}),nonce); | |
| if(!await page.evaluate(()=>window.browserPi.rpc('cache_status')))await page.evaluate(()=>window.browserPi.load()); | |
| await page.evaluate(()=>{ | |
| window.meterStates=[]; | |
| new MutationObserver(()=>window.meterStates.push({state:document.querySelector('#runtime-meter').dataset.state,value:document.querySelector('.runtime-value').textContent})).observe(document.querySelector('#runtime-meter'),{attributes:true,attributeFilter:['data-state']}); | |
| }); | |
| await page.locator('.xterm-helper-textarea').focus();await page.keyboard.type('Read meter-check.txt using the read tool and tell me its exact contents.');await page.locator('#send').click(); | |
| await page.waitForFunction(()=>window.browserPi.diagnostics.runtimeSamples.some(s=>s.phase==='decode'&&s.rate>0)); | |
| await page.locator('header').screenshot({path:`../validation/${label}-live.png`}); | |
| await page.waitForFunction(()=>!window.browserPi.busy&&window.browserPi.diagnostics.events.includes('agent_end')); | |
| const state=await page.evaluate(()=>window.browserPi.rpc('snapshot')); | |
| result.states=await page.evaluate(()=>window.meterStates); | |
| result.samples=await page.evaluate(()=>window.browserPi.diagnostics.runtimeSamples); | |
| assert(result.states.some(s=>s.state==='prefill')); | |
| assert(result.states.some(s=>s.state==='generating'&&/tok\/s/.test(s.value))); | |
| assert(result.states.some(s=>s.state==='tool')); | |
| assert(result.samples.filter(s=>s.rate!==undefined&&s.rate!==null).every(s=>Number.isFinite(s.rate)&&s.rate>=0)); | |
| assert(state.messages.filter(m=>m.role==='assistant').at(-1).content.some(c=>c.text?.includes(nonce))); | |
| assert.equal(await page.locator('#filename').textContent(), '/workspace/meter-check.txt'); | |
| assert.equal(await page.locator('#editor').inputValue(), nonce); | |
| assert.equal(await page.locator('.runtime-value').textContent(),'Ready'); assert(!await page.locator('.runtime-sparkline').isVisible()); | |
| result.checks.push('Actual WebGPU token callbacks drive live rates, with distinct prefill, tool and idle states and a verified file result'); | |
| await page.locator('.xterm-helper-textarea').focus();await page.keyboard.type('Count from 1 to 200.');await page.locator('#send').click(); | |
| await page.waitForFunction(()=>document.querySelector('#runtime-meter').dataset.state==='generating');await page.locator('#stop').click(); | |
| await page.waitForFunction(()=>!window.browserPi.busy); | |
| assert.equal(await page.locator('.runtime-value').textContent(),'Ready'); assert(!await page.locator('.runtime-sparkline').isVisible()); | |
| result.checks.push('Stopping generation clears the live rate and chart'); | |
| assert.deepEqual(result.errors,[]);result.passed=true;console.log(JSON.stringify({passed:true,checks:result.checks,samples:result.samples.length})); | |
| } catch(error){result.failure=error.stack;throw error;} | |
| finally{await fs.writeFile(`../validation/${label}.json`,JSON.stringify(result,null,2));await context?.close();await browser.close();} | |