fix(ai): resolve the ONNX wasm directory against the app, not the route - #2863
fix(ai): resolve the ONNX wasm directory against the app, not the route#2863wayfarer3130 wants to merge 2 commits into
Conversation
`getConfig` set `ort.env.wasm.wasmPaths = 'ort/'`. That prefix is document-relative, so the browser resolves it against the current route rather than against the application. It only finds the copy of `onnxruntime-web/dist` when the page sits exactly one segment deep, which is why it works for the examples and for `viewer.ohif.org/segmentation`. A viewer served from a deeper route — `/viewer/dicomweb`, say — requests `/viewer/ort/ort-wasm-*.wasm`, gets the SPA fallback's `index.html`, and compiling that as WebAssembly fails with `expected magic word 00 61 73 6d, found 3c 21 64 6f`. ONNX then reports "no available backend found", the SAM controller never finishes loading, and the failure surfaces to the user as a broken labelmap tool. Resolve the prefix against the base the bundler already uses for the assets it emits — webpack/rspack's public path, falling back to `document.baseURI` — which is the directory applications copy `onnxruntime-web/dist` into. The example runner copies it to `<example>/ort` and is served with `publicPath: 'auto'`, so examples resolve to the same URL they do today. Also stop overwriting a location the application configured: apps serving the binaries from a CDN or a versioned path had their setting clobbered from every `ONNXSegmentationController` construction. Locating the binaries with `new URL(<specifier>, import.meta.url)`, the way the codec and worker assets are located, is not available here: `onnxruntime-web@1.17` publishes only its JavaScript entry points through `exports`, so `onnxruntime-web/dist/ort-wasm-simd.jsep.wasm` does not resolve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change adds browser-aware ONNX Runtime WebAssembly path resolution. The segmentation controller preserves an existing configured path and resolves a fallback path through the new utility. ChangesONNX Runtime WebAssembly paths
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized change anchors ONNX WebAssembly assets to the application base while preserving application-configured paths; no actionable merge-blocking risk remains beyond normal checks. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Resolve a relative public path against `document.baseURI` (falling back to `location.href`, for workers) rather than against `location.href` alone. That is the definition webpack and rspack generate for `__webpack_require__.b`, which is the base `new URL(<specifier>, import.meta.url)` compiles down to — so the ONNX binaries now resolve against exactly the same base as the codec wasm. Only observable with a relative public path and a `<base>` tag; identical everywhere else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Superseded by #2864 — same commits, from a branch on the repo rather than a fork. |
Context
ONNXSegmentationController.getConfig()points ONNX Runtime at its WebAssembly binaries withThat prefix is document-relative. The browser resolves it against the current route rather than against the application, so it only lands on the copy of
onnxruntime-web/distwhen the page sits exactly one segment deep — which is why it works for the examples and forviewer.ohif.org/segmentation.Problem
A viewer served from a deeper route (
/viewer/dicomweb,<PUBLIC_URL>viewer/<dataSource>, …) requests<route>/ort/ort-wasm-*.wasm. Nothing is served there: the SPA fallback answers withindex.html, and compiling that as WebAssembly dies withONNX then reports
no available backend found, the SAM controller never finishes loading, and the next viewport render throws on the labelmap it never got. Downstream (OHIF/Manta) this reaches the user as a generic "Something went wrong" on the labelmap assist tool, and every consumer whose viewer is not at a single-segment route has to patch it in application code.The second half of the problem is that the assignment runs from every
ONNXSegmentationControllerconstruction, so an application that setsort.env.wasm.wasmPathsitself (a CDN, a versioned path) has its value clobbered — patching it from the app requires trapping the write with an accessor rather than simply assigning.Change
packages/ai/src/utils/getOrtWasmPaths.tsresolves the prefix to an absolute URL against the base the bundler already uses for the assets it emits — webpack/rspack's public path (__webpack_public_path__), falling back todocument.baseURI, and to the bare'ort/'outside a browser.getConfig()only setswasmPathswhen the application has not already set it.Why not
new URL(..., import.meta.url)Every other wasm binary here is located the way the codecs and workers do it —
new URL('@cornerstonejs/codec-charls/decodewasm', import.meta.url)— letting the bundler resolve, emit and hash the file. That is not available for ONNX atonnxruntime-web@1.17: itsexportsmap publishes only the JavaScript entry points, soApplications therefore copy
onnxruntime-web/distnext to their bundle (this repo'sutils/ExampleRunner/template-config.jscopies it to<example>/ort) and point the runtime at the copy. Anchoring that copy to the bundle's public path is the closest equivalent, and it is the same base the emitted asset URLs carry. Whenonnxruntime-webis eventually bumped to ≥ 1.21, its*.bundle.min.mjsbuilds resolve their own.wasmthroughimport.meta.urland this whole assignment can be deleted.Impact
publicPath: 'auto', ort copied to<example>/ort)<example>/ort/<example>/ort/— unchanged<root>/ort/<root>/ort/— unchanged<route>/ort/— 404 / index.html<root>/ort/wasmPathsNo new work at load time: one URL resolution, once, inside
getConfig(). No change to what is fetched or when.Testing
PUBLIC_URL=/pacs/+ deep route,publicPath: 'auto'as the example runner uses, no bundler with and without a<base>tag, and a non-browser context).publicPathat'auto'and copiesonnxruntime-web/distbeside the bundle.Summary by CodeRabbit