fix(stage-ui): prevent Kokoro fp32-webgpu hang and fix STT mic device enumeration#1638
fix(stage-ui): prevent Kokoro fp32-webgpu hang and fix STT mic device enumeration#1638ENTWOPY wants to merge 4 commits intomoeru-ai:mainfrom
Conversation
On first visit to the Kokoro TTS settings page, config.model is undefined so validateProviderConfig fails and the model/voices never load. Auto-save the hardware-appropriate default (q4f16 for WASM, fp32-webgpu for WebGPU) before validation so the model initialises correctly without requiring manual selection.
…eration - kokoro/constants: always default to q4f16 (WASM, ~320MB) instead of fp32-webgpu (~700MB) to avoid indefinite page hang on first visit; WebGPU model is still selectable manually via the dropdown - kokoro-local.vue: also migrate existing saved fp32-webgpu config to q4f16 on page mount so returning users are unblocked without a reset - audio-device.ts: add reverse watcher so when the composable auto-selects a default device after permission is granted the selected device ID is written back to persisted storage, keeping the dropdown and stream in sync across reloads - hearing.vue: call askPermission() in onMounted so the browser permission dialog fires immediately and the audio input dropdown is populated when the user first opens the Hearing settings page
There was a problem hiding this comment.
Code Review
This pull request improves the initialization of audio devices and optimizes the default Kokoro model selection to prevent performance issues. It now requests microphone permissions on mount to populate the device list immediately and defaults to the lighter 'q4f16' model to avoid long downloads. Feedback was provided to ensure that errors during the permission request are surfaced to the user, as the current implementation silently catches them, which could leave the user confused if the device list remains empty.
| askPermission().catch(() => { | ||
| // Permission denied — the dropdown will remain empty and the user will see a warning. | ||
| }) |
There was a problem hiding this comment.
The askPermission() call catches errors but doesn't surface them to the user, despite the comment stating that the user will see a warning. If microphone permission is denied, the audio input dropdown will remain empty without any feedback, which can be confusing for users. It's better to capture the error and display it using the existing error ref so the user understands why the device list is empty.
askPermission().catch((err) => {
// Permission denied — the dropdown will remain empty.
// We surface the error so the user knows why devices are missing.
error.value = err instanceof Error ? err.message : String(err)
})
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b4128d768
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!config.model || config.model === 'fp32-webgpu') { | ||
| config.model = getDefaultKokoroModel(hasWebGPU.value) |
There was a problem hiding this comment.
Preserve user-selected fp32-webgpu model
This condition rewrites config.model from fp32-webgpu to q4f16 on every page mount, so users who explicitly choose the WebGPU model cannot persist that choice across navigation/reload. In practice, the app will silently revert them each time they revisit Kokoro settings, which breaks expected settings persistence and makes manual opt-in effectively non-sticky.
Useful? React with 👍 / 👎.
Add pattern to TOOLS_RELATED_ERROR_PATTERNS matching Groq's 400 response "property 'X' is unsupported" — triggered by OpenAI-specific tool params (e.g. capture_tool_errors) that the xsai library sends unconditionally. On first failure airi now auto-retries without tools instead of surfacing a raw 400 error to the user.
|
Rebase is needed, it conflicted. |
Summary
getDefaultKokoroModelnow always returnsq4f16(WASM, ~320 MB) instead offp32-webgpu(~700 MB). The WebGPU model caused the settings page to become unresponsive on first load while the worker silently attempted a massive background download. Users who want the full-precision WebGPU model can still select it manually.fp32-webgpusaves are migrated —kokoro-local.vuenow also migrates any already-savedfp32-webgpuconfig toq4f16on mount, so returning users are unblocked without having to manually reset their settings.hearing.vuenow callsaskPermission()inonMountedso the browser permission dialog fires immediately when the user opens the Hearing page. Previously the dropdown stayed empty until the user manually triggered device enumeration, making STT look completely broken.audio-device.tsadds a reverse watcher: when theuseAudioDevicecomposable auto-selects a default mic after permission is granted, that selection is written back tolocalStorage. Without this, the dropdown and the audio stream could fall out of sync across reloads.Test plan
q4f16should be selected automaticallyfp32-webgpupreviously saved inlocalStorage— page should migrate toq4f16on mount instead of hanging🤖 Generated with Claude Code