Repository navigation
Pin agent-browser; check the terrain gallery's WebGPU from the lab's own pixels - #5220
Merged
Merged
Conversation
agent-browser 0.42.0 (published 00:40Z) relaunches the browser when a command names launch settings the running one lacks. The gallery gave its GPU flags on one command and --ignore-https-errors on another, so the page loaded in a fresh browser without its viewport. There three.js got a WebGPU adapter for the first time, and headless Linux Chrome never puts a WebGPU canvas into a screenshot: blank captures since 08:42Z. Under 0.41.2 the same flags had been dropped too, and "webgpu-auto" had quietly rendered on WebGL2 every run. - Pin agent-browser in one module that every script spawns from. - createBrowserSession gives its launch settings (GPU flags, the dev server's certificate, init script, extra Chrome flags) on every command and refuses them on a single one. Its callers move theirs onto the session. - The gallery fails a capture that rendered on another backend than asked. - CI runs the gallery headed on Xvfb with agent-browser's WebGPU preset.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 3 Skipped Deployments
|
agent-browser allows SwiftShader only for headless launches. CI runs the terrain
gallery headed on Xvfb with no GPU, so its first run had no WebGL context and no
WebGPU adapter ("Cannot read properties of null (reading 'getSupportedExtensions')").
Its run (42807386669) answered the question: on the runner, headless Chrome renders WebGPU but never captures it, and a headed launch gets no WebGPU adapter.
The class: a CI tool floating to latest. agent-browser 0.42.0 (published 00:40Z) turned the terrain gallery's WebGPU captures blank on every run since. - lib/agent-browser.mjs holds the one version; the four spawns (the session behind the prove and playtest scripts, both smoke runners behind prove-run, the terrain benchmark) read it. - lint-guards refuses a script that spawns agent-browser by name. - The session, gallery, workflow and callers go back to next's code. The launch-settings and WebGPU-check work returns with the in-page pixel check, which it needs to pass on a GPU-less runner.
webgpu-auto had rendered on WebGL2 on every passing run: the session's GPU flags were dropped when a later command relaunched the browser. With them kept, the captures came out blank, because headless Chrome on Linux (SwiftShader, no GPU) puts a WebGPU canvas into neither a screenshot nor a canvas copy. - The terrain lab's captureFrame draws one frame into a render target as the screen output and reads its pixels back; the gallery saves that PNG and checks the share drawn over the clear colour. - The gallery fails a capture rendered on another backend than it asked for. - createBrowserSession gives its launch settings on every command and refuses them on a single one; its eight callers move theirs onto the session, and two "open the address again" workarounds go.
… driver On the runner (no GPU, no Vulkan driver) Chrome destroys the first WebGPU device about two seconds after it starts. three skips its onDeviceLost for a device lost as "destroyed", so the lab stayed ready and drew nothing; the readback then failed with "A valid external Instance reference no longer exists" (run 42811058562). - The lab watches its device's lost promise and ends in an error that names it; the gallery reports the lab's error. - CI installs Mesa's software Vulkan driver (libvulkan1, mesa-vulkan-drivers), which keeps the device alive.
djizus
marked this pull request as ready for review
November 10, 2026 12:30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
terrain / galleryfailed on every run that reached it from 08:42Z on 10 November,nextincluded: the twowebgpu-autocaptures came out blank.Cause
The scripts ran
npx -y agent-browserunpinned, so each run fetched the newest. agent-browser 0.42.0 was published at 00:40Z, four minutes after the last passing run started.next(42784883691, 08:45Z)webgpu-autorendered onwebgl2-fallbackwebgpu--ignore-https-errorson another.set viewport, sowebgpu-autohad quietly rendered on WebGL2 on every passing run.--ignore-https-errors. In that browser three.js got WebGPU, which headless Linux Chrome never puts into a screenshot.No merged change caused it.
Fix
1. Pin agent-browser (
339c00dffb9).apps/game/scripts/lib/agent-browser.mjsholds one version, 0.41.2, and all four spawns read it.lint-guards(client CI) refuses a script that spawns agent-browser by name.2. Check WebGPU on WebGPU (
d462aec28f9).captureFramedraws one frame into a render target as the screen output (tone mapped, sRGB) and reads its pixels back.createBrowserSessionsends its launch settings on every command and refuses them on a single one. Its eight callers move theirs onto the session.3. Keep the WebGPU device alive (
652152a984f).onDeviceLostfor a device lost as "destroyed", so the lab stayed ready and drew nothing. That is likely what blanked the original captures too.lostpromise and ends in an error that names it; the gallery reports it.libvulkan1,mesa-vulkan-drivers), which keeps the device alive.Verification
webgpu-autorenders on WebGPU (SwiftShader) with coverage 0.59; with step 1's canvas copy it read 0.next's code and pass here. The guard flags both an argv spawn and a shell-string spawn.format,knip,lint:guards.terrain / gallerygreen on652152a984f(42813439054).webgpu-autorenders on WebGPU (coverage 0.58),webgpu-force-webglon WebGL2 (0.58–0.59), and the contact sheet shows the terrain from both.Follow-up, not here
The game's own renderer (
webgpu-renderer-backend.ts) also learns of a lost device only through three'sonDeviceLost, so it would miss a device Chrome destroys this way.The other agent-browser wrappers (
runAgentBrowserin the two smoke runners, behindprove-run.mjs,capture-hud-laband about 25prove-*scripts) still pass--ignore-https-errorson single commands. Under 0.41.2 that does not relaunch the browser. Moving them ontocreateBrowserSessionwould let the pin move to 0.42.0.