What happens
window.HyperaudioModelStores is the right seam — an engine declares where its models live and settings.js lists and removes them without knowing any engine by name. But the registry entry is a cacheName, and the module consumes it exclusively through CacheStorage:
if (!(await caches.has(store.cacheName))) continue;
const cache = await caches.open(store.cacheName);
…
await caches.delete(store.cacheName);
An embedder whose engine downloads models to the filesystem rather than a browser cache therefore cannot register at all. The row is not merely empty for it — it says "None downloaded." while a couple of gigabytes sit on disk, which is worse than showing nothing.
That is the position of any host that supplies its own ASR: the editor's own in-browser engines are hidden, one native model does the work, and the panel that exists to tell you what you have downloaded tells you the opposite.
Suggested change
Let a store supply its own accounting, and keep the CacheStorage path as the default so nothing registered today has to change:
(window.HyperaudioModelStores = window.HyperaudioModelStores || []).push({
engine: 'Parakeet (native)',
// either the existing cacheName…
cacheName: 'parakeet-models',
// …or the host's own answers
list: async () => [{ label: 'Parakeet TDT 0.6B v3', bytes: 2_147_483_648 }],
remove: async (label) => { /* host deletes it; resolves when gone */ },
});
settings.js would use list/remove when present and fall back to the cache path otherwise. The grouping, the totals and the per-model rows all stay as they are — only the source of the entries changes.
Why it is worth a seam rather than the embedder hiding the row
Hiding is what an embedder has to do today, and it loses a real capability: the host usually can delete its models, it just cannot say so here. The three browser engines and a native one differ only in where the bytes are, which is exactly the kind of difference a registry is supposed to absorb.
Happy to send a PR if the shape looks right.
What happens
window.HyperaudioModelStoresis the right seam — an engine declares where its models live andsettings.jslists and removes them without knowing any engine by name. But the registry entry is acacheName, and the module consumes it exclusively through CacheStorage:An embedder whose engine downloads models to the filesystem rather than a browser cache therefore cannot register at all. The row is not merely empty for it — it says "None downloaded." while a couple of gigabytes sit on disk, which is worse than showing nothing.
That is the position of any host that supplies its own ASR: the editor's own in-browser engines are hidden, one native model does the work, and the panel that exists to tell you what you have downloaded tells you the opposite.
Suggested change
Let a store supply its own accounting, and keep the CacheStorage path as the default so nothing registered today has to change:
settings.jswould uselist/removewhen present and fall back to the cache path otherwise. The grouping, the totals and the per-model rows all stay as they are — only the source of the entries changes.Why it is worth a seam rather than the embedder hiding the row
Hiding is what an embedder has to do today, and it loses a real capability: the host usually can delete its models, it just cannot say so here. The three browser engines and a native one differ only in where the bytes are, which is exactly the kind of difference a registry is supposed to absorb.
Happy to send a PR if the shape looks right.