Skip to content

Repin WebGPU bridge assets to v0.1.67 - #1260

Closed
leehack wants to merge 2 commits into
mainfrom
chore/webgpu-bridge-v0.1.67
Closed

leehack wants to merge 2 commits into
mainfrom
chore/webgpu-bridge-v0.1.67

Conversation

@leehack

@leehack leehack commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Repin the default WebGPU bridge assets from v0.1.66 to the immutable leehack/llama-web-bridge-assets@v0.1.67: release 419092691, tag commit 2657686bd3956c09ab60fe89ca7d6d660045b5e3, bridge source 8992121b4b533a4444ad6de93d855ea3c99644c6, manifest SHA-256 d596304c609034afc37280bf86b8231a941bf3a7f3a3e584acd084f646a472ba. Same llama.cpp v0.7.0@620d2225… and native v0.7.0-1 as before.
  • The bridge source diff from v0.1.66 is exactly three commits: bridge#166 (fixes bridge#113: relative model and media URLs in worker mode), bridge#167 (fixes bridge#150: await WebGPU free_model/shutdown), and bridge#168 (fixes bridge#116: a missing state file rejected instead of aborting the core). The .d.ts and worker script are byte-identical, so the Dart interop and public API are unchanged.
  • Adds test/e2e/webgpu/bridge_runtime_fixes_e2e_test.dart (local-only, real assets, worker and direct runtimes). It fails on v0.1.66 and passes on v0.1.67.

Refs #922 (0.15.6 lane "bridge#113, #150, #116 (bridge v0.1.67 repin)"). No dedicated llamadart issue tracks these fixes.

Production-readiness scope

  • User-facing scope: On Web GGUF, stateLoadFile on a missing or directory path, and stateSaveFile into a missing directory, throw LlamaStateException ("Cannot open state file …"). The runtime stays usable and the worker stays a worker; before, it threw Aborted(undefined) and the core was dead. A chat LlamaImageContent.url relative to the page now loads in worker mode; before, it hit a 404 (CPU) or silently moved the bridge to the main thread (WebGPU). Bridge teardown awaits the WebGPU free and shutdown.
  • Supported platforms/paths: Web llama.cpp/GGUF bridge, direct and worker runtimes, wasm32 (verified) and memory64 (bridge-qualified).
  • Unsupported or intentionally unavailable paths: WASMFS state paths are still lost on page reload (documented); durable state stays #1160. Truncated state snapshots can still abort the core (bridge#169).
  • Out of scope / follow-ups: bridge#169. The chore(native): sync native release b9159 #150 same-bridge reload is not reachable through llamadart: WebGpuLlamaBackend.modelFree disposes the bridge and the next load builds a new one. Unload/reload passes on v0.1.66 WebGPU too, so the changelog makes no reload claim.

Completeness checklist

  • Declared scope is fully implemented, or explicitly reduced above.
  • Unsupported platform/option combinations fail loudly with actionable diagnostics or are clearly documented as unavailable.
  • Public API docs, README/website docs, examples, support matrices, and changelog entries are updated where relevant. Pin sites, provenance, v0.1.67+ capability history, the Web state-file note, the multimodal relative-URL note, the llamadart-web skill and the Unreleased changelog in both files.
  • Regression coverage covers the original issue plus key negative/version-skew paths where relevant. Real-asset e2e with v0.1.66 causal controls; it also checks that the relative URL would not resolve against the worker script.
  • Public capability changes update the validation coverage registry with a pack or a reasoned, issue-linked exemption; inventory checks pass (or N/A with scope). N/A: no new public capability. This is a behavior fix of the existing state persistence and media URL inputs.
  • Security/privacy review completed: no secrets, bearer tokens, signed URLs, or raw secret-bearing paths leak through logs, cache keys, metadata, errors, or snapshots. State errors still go through webGpuBridgeErrorText(sourceUrls: [path]) redaction.
  • Follow-up work that is useful but not required for this PR is tracked in GitHub Issues, or explicitly marked "None" above.

PR type guidance

  • Feature PR: N/A. Pin bump.
  • Bugfix PR: The root causes are in the bridge (bridge#166/Add LiteRT-LM native backend support #167/MTP support? #168 bodies). The consumer regression is bridge_runtime_fixes_e2e_test.dart. Platforms: Web only (Chrome CPU wasm32 and Chrome WebGPU/Metal on macOS arm64).
  • Docs-only PR: N/A.

Test Plan

Correction. The first head ac5101e failed the tag gate: the e2e header spelled the pinned tag, and the gate scans tracked files. My earlier gate, tag-test and VM runs happened while that file was still untracked, so they did not reflect ac5101e. eb081ed rewords the header. The results below are measured at eb081ed unless marked otherwise.

At eb081ed:

  • dart format --output=none --set-exit-if-changed . (pinned Flutter 3.47.1): 0 changed
  • dart analyze: no issues
  • dart run tool/testing/check_webgpu_bridge_tag.dart: exit 0 (18 pins on v0.1.67)
  • dart run tool/testing/check_webgpu_bridge_tag.dart --verify-manifest: exit 0 (live manifest, release 419092691)
  • dart test -p vm test/unit/tooling/: 883 passed, 4 skipped. This includes check_webgpu_bridge_tag_test.dart 62/62
  • TMPDIR=<fresh> dart test -p vm -j 1 --exclude-tags local-only: not run at this head. The host's 1-minute load was 25.95, above the 24 limit. The earlier full-lane count is not valid for either head
  • dart run tool/prepare_workspace.dart, check_platform_boundaries: not rerun at this head. They passed on the ac5101e tree, and eb081ed changes only two doc-comment strings in a local-only test

Measured on the ac5101e tree. The code and assets are identical at eb081ed; only two doc-comment strings in the local-only e2e test differ:

  • dart test -p chrome --exclude-tags local-only: 3502 passed
  • Chat app: flutter test test test_vm 672 passed (4 skipped); the Web-only chrome set 126 passed
  • Web smokes, docs build and the real-asset e2e: see below

Real-asset regression (bridge_runtime_fixes_e2e_test.dart)

Fixtures: stories15M (212ddc79…), LFM2-VL-450M-Q4_0 (1fbf4797…) + mmproj Q8_0 (a6a813fa…), a 64×64 PNG. Assets come from fetch_webgpu_bridge_assets.sh with checksums verified. Chrome uses SharedArrayBuffer; the WebGPU runs add --enable-unsafe-webgpu --use-angle=metal --headless=new (backend WebGPU, CPU).

Assets Backend Reload Missing state file Relative image URL Result
v0.1.67 CPU wasm32 worker ✓ direct ✓ worker ✓ direct ✓ worker ✓ direct ✓ 6/6
v0.1.67 WebGPU worker ✓ direct ✓ worker ✓ direct ✓ worker ✓ direct ✓ 6/6
v0.1.66 (control) CPU wasm32 ✓ ✓ ✗ Aborted(undefined) both ✗ worker: Failed to fetch media: 404 3/6
v0.1.66 (control) WebGPU ✓ ✓ ✗ Aborted(undefined) both ✗ worker: bridge left the worker runtime 3/6

In both runtimes, the URL reply equals the bytes reply under greedy decoding.

Matrix Evidence

Matrix row Scope covered Platform / model / backend Result Evidence / notes
static-format-analyze format, analyzer, web/native import boundaries macOS arm64, Flutter 3.47.1 PASS prepare_workspace, format, analyze, platform boundaries
root-vm native-safe unit/integration coverage on the Dart VM macOS arm64 Not run at head Host load 25.95 (above 24). test/unit/tooling/ 883 passed at eb081ed; the full lane is left to CI
root-chrome browser-compatible unit/integration coverage Chrome PASS 3502 passed
webgpu-bridge-tag-consistency every site pinning the WebGPU bridge asset tag matches the fetch script default, and the bridge assets' llama.cpp build matches the native pin unless a divergence is recorded live GitHub/jsDelivr manifest PASS (at eb081ed) Gate exits 0 with and without --verify-manifest: 18 pins on v0.1.67, Web/native v0.7.0, provenance for release 419092691. jsDelivr manifest.json is byte-identical to the release asset. Tag test 62/62. ac5101e failed this gate (see Test Plan)
docs-site website build, docs metadata, generated docs routes local PASS ./tool/docs/build_site.sh: 2612 pages, no broken internal links
web-bridge-smoke WebGPU bridge bootstrap and fallback wiring Chrome, packaged chat app PASS run_local_e2e.dart --scenario bridge-smoke on checksum-verified v0.1.67, worker calls for load/projector/completion
web-mock-chat-smoke built Flutter web chat app with deterministic mock bridge Chrome PASS --scenario chat-app-web-mock-smoke
web-real-model-smoke built Flutter web chat app with real worker/WASM and GGUF model URL Chrome CPU, Qwen3.5-0.8B-Q4_K_M PASS --scenario chat-app-web-real-model-smoke: runtime v0.1.67-local-v0.7.0, reply "2+2 equals 4."
web-production-artifact-smoke one production-root build tested by mock and real worker/GGUF smokes Chrome CPU, stories15M PASS --scenario chat-app-web-production-smoke
web-multimodal-embeddings Direct/worker Web text/image/audio/mixed vectors against local native references, normalization, order and adjacent text — N/A EmbeddingGemma-2 weights and reference vectors unavailable locally. The bridge diff does not touch embedding compute, and the hosted multimodal gate passed (manifest qualification_gates.multimodal: passed). Doc states the last consumer rerun was on v0.1.66
web-text-to-speech-smoke published WebGPU bridge, public typed TTS API, Qwen3-TTS catalog, optional byte-backed speaker reference, progress, complete 24 kHz PCM, chat-app autoplay, and downloaded WAV validation — N/A Bridge diff does not touch TTS. The hosted TTS attestation passed for v0.1.67
web-speech-to-text-smoke published WebGPU bridge, public typed STT API, Qwen3-ASR catalog, exact browser-selected WAV, MP3 or FLAC transcription, non-empty fake-device microphone transcription for a WAV, and rendered transcripts — N/A Bridge diff does not touch ASR. The hosted ASR attestation passed for v0.1.67
webgpu-multimodal-regression CPU and WebGPU Qwen multimodal regression path Chrome CPU + WebGPU, LFM2-VL-450M Covered by e2e Relative-URL image completion on CPU and WebGPU, both runtimes (table above). The scenario itself was not run
high-risk-exact-head-independent-qa independent blocking-only review of exact head/current base, live threads, production call sites, adversarial negatives, and tests sensitive to production-branch deletion, bypass, or miswiring — Pending Required before ready: classifier says high-risk (artifactConsumer)

Review Notes

  • Independent review status: pending independent blocking-only audit of the exact head.
  • Independent audit of ac5101e found one blocking P1: the tag-gate failure above. It is fixed in eb081ed and needs re-audit at the new head.
  • CI status / head SHA: head eb081edb4084d2df4a896514a790da4a6d411ad2 on base 2dc1fbbb223f664581d587f6fea04c0d52a7bd62; CI pending.

High-risk regression review

  • Classification: high-risk (classify_high_risk_changes.dart: surfaces artifactConsumer)
  • Implementation task: this PR (bridge pin, provenance gate constants, docs, local-only real-asset e2e)
  • Independent blocking QA task: pending; must be a fresh session uninvolved in this implementation
  • Exact head / current base: eb081edb4084d2df4a896514a790da4a6d411ad2 / 2dc1fbbb223f664581d587f6fea04c0d52a7bd62
  • Production-branch deletion, bypass, or miswire proof: the e2e fails on the previous pin (v0.1.66) for the state and worker relative-URL cases on CPU and WebGPU, and passes on v0.1.67. A precondition fails the test if the relative URL would also resolve against the worker script. The tag gate rejects pin and manifest-hash drift; --verify-manifest checks the live manifest bytes and their provenance fields, but not the release id or tag commit (verified by hand here; gate gap tracked separately)
  • Affected-family real-model/artifact evidence: exact published v0.1.67 assets (checksum-verified) with stories15M, LFM2-VL-450M + mmproj and Qwen3.5-0.8B (chat smoke)
  • Explicit unavailable-family or other N/A evidence: EmbeddingGemma-2 (web-multimodal-embeddings), Qwen3-TTS/ASR Web smokes. Weights unavailable locally or the path is untouched by the bridge diff; the hosted bridge gates passed
  • Known PR-caused P1 regressions: 0 open. The audit P1 at ac5101e (tag gate) is fixed in eb081ed and awaiting re-audit
  • Unresolved review threads: 0

Independent re-audit at eb081ed: PASS (delta: two doc-comment strings in the local-only e2e; tag gate with/without --verify-manifest exit 0; tooling 883 passed; boundaries OK; full VM lane not run due to machine load; hosted CI pending).

Adopt the immutable llama-web-bridge-assets release v0.1.67 (release
419092691, tag commit 2657686, bridge source 8992121, manifest SHA-256
d596304c...), built for native v0.7.0-1 on the same llama.cpp v0.7.0.
It carries bridge fixes for missing state files aborting the core
(bridge#116), worker-mode relative media URLs (bridge#113) and unawaited
WebGPU free/shutdown ccalls (bridge#150).

Add a local-only real-asset Chrome test covering both runtimes; it fails
on v0.1.66 assets and passes on v0.1.67, on CPU and WebGPU.
The tag gate scans tracked files for unregistered spellings of the pinned tag, so the local-only e2e test must name the pinned assets without the tag.
@github-actions

Copy link
Copy Markdown
Contributor

Chat app preview deployed for eb081ed.

@leehack leehack mentioned this pull request Oct 21, 2026
16 tasks done
@leehack

leehack commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Independent audit record: blocking-only adversarial audit of exact head eb081edb4084d2df4a896514a790da4a6d411ad2 by a fresh agent session that took no part in the implementation. Verdict: PASS; 0 known PR-caused P1 regressions; 0 unresolved review threads. This PR lands through the batch integration PR #1282.

@leehack

leehack commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Landed on main through batch integration PR #1282 (rebase merge 9ee96c3; tree identical to the audited integration head).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant