fix(studio): a repair lands under the brush with no pill over it, and a browser with no device is not asked for one

This commit is contained in:
2026-10-14 08:59:13 +07:00
parent 24ce97edcc
commit 5aa6a5ba23
4 changed files with 28 additions and 11 deletions
+22 -6
View File
@@ -71,16 +71,32 @@ async function warmsUp(ort: typeof Ort, session: Ort.InferenceSession): Promise<
}
}
// Whether the browser has a device at all. `requestAdapter` answers for the
// browser and not for this graph — an adapter is no promise the model runs on
// it, the trial below is what settles that — but a *null* answer is a promise
// it does not, and the attempt it saves is not nothing: a `create` that cannot
// have a device still opens a session and tears it down (measured: 0.4s off the
// first repair, and one backend fewer built on the way to the one that lasts).
async function hasDevice(): Promise<boolean> {
try {
return Boolean(await navigator.gpu?.requestAdapter());
} catch {
return false;
}
}
// WebGPU first, the processor as the answer to every way that can fail: no
// adapter, no `shader-f16` needed here but an op the provider never
// implemented, a driver that opens a session and dies on the first dispatch.
async function openSession(ort: typeof Ort): Promise<Ort.InferenceSession> {
try {
const gpu = await ort.InferenceSession.create(MODEL_URL, { executionProviders: ['webgpu'] });
if (await warmsUp(ort, gpu)) return gpu;
await gpu.release();
} catch {
// Whatever went wrong, the wasm provider is the fallback and not a failure.
if (await hasDevice()) {
try {
const gpu = await ort.InferenceSession.create(MODEL_URL, { executionProviders: ['webgpu'] });
if (await warmsUp(ort, gpu)) return gpu;
await gpu.release();
} catch {
// Whatever went wrong, the wasm provider is the fallback and not a failure.
}
}
return ort.InferenceSession.create(MODEL_URL, { executionProviders: ['wasm'] });
}