diff --git a/.mise.toml b/.mise.toml index bb64685..a3b91c7 100644 --- a/.mise.toml +++ b/.mise.toml @@ -6,6 +6,7 @@ cmake = "latest" dprint = "latest" editorconfig-checker = "latest" "github:block/goose" = "latest" +"github:wasm-bindgen/wasm-bindgen" = "0.2.114" ollama = "latest" osv-scanner = "latest" pipx = "latest" @@ -68,7 +69,11 @@ run = "cargo run" [tasks.build-ws-wasm-agent] description = "Build the WebSocket WASM client" dir = "services/ws-wasm-agent" -run = "wasm-pack build --target web" +run = "wasm-pack build . --target web -- -Z build-std=std,panic_abort" + +[tasks.build-ws-wasm-agent.env] +RUSTFLAGS = "-C target-cpu=mvp -C target-feature=+mutable-globals,+sign-ext,+nontrapping-fptoint" +RUSTUP_TOOLCHAIN = "nightly" [tasks.test-ws-wasm-agent-firefox] description = "Run headless Firefox tests for the WebSocket WASM client" diff --git a/README.md b/README.md index fd164c9..57531f3 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ mise run build-ws-wasm-agent mise run ws-server ``` +The WASM build disables WebAssembly reference types so it can still load on older browsers such as Chrome 95. + Find the IP address of your laptop in the local network, which will normally be something like 192.168.1.x. diff --git a/services/ws-server/static/app.js b/services/ws-server/static/app.js index 8a4f0b3..3caa152 100644 --- a/services/ws-server/static/app.js +++ b/services/ws-server/static/app.js @@ -131,6 +131,33 @@ const formatNumber = (value, digits = 3) => ( Number.isFinite(value) ? value.toFixed(digits) : "n/a" ); +const configureOnnxRuntimeWasm = () => { + if (!window.ort?.env?.wasm) { + throw new Error("onnxruntime-web environment is unavailable."); + } + + const ortVersion = window.ort.env.versions?.web; + if (typeof ortVersion !== "string" || ortVersion.length === 0) { + throw new Error("onnxruntime-web version is unavailable."); + } + + const distBaseUrl = `https://cdn.jsdelivr.net/npm/onnxruntime-web@${ortVersion}/dist`; + const supportsWasmThreads = window.crossOriginIsolated === true + && typeof SharedArrayBuffer !== "undefined"; + + window.ort.env.wasm.numThreads = supportsWasmThreads ? 0 : 1; + window.ort.env.wasm.wasmPaths = { + mjs: `${distBaseUrl}/ort-wasm-simd-threaded.mjs`, + wasm: `${distBaseUrl}/ort-wasm-simd-threaded.wasm`, + }; + + append( + `onnxruntime-web configured: version=${ortVersion} wasm=${window.ort.env.wasm.wasmPaths.wasm} threads=${ + window.ort.env.wasm.numThreads === 1 ? "disabled" : "auto" + }`, + ); +}; + const degreesToRadians = (value) => ( Number.isFinite(value) ? (value * Math.PI) / 180 : 0 ); @@ -797,6 +824,8 @@ try { throw new Error("onnxruntime-web did not load."); } + configureOnnxRuntimeWasm(); + harButton.disabled = true; harButton.textContent = "Loading HAR..."; updateHarStatus(["loading model..."]);