fix(web): clean up voice settings#31526
Problem
The Voice settings page separates microphone and model tests from their settings by placing them below the full model catalog. The model test renders a streaming preview separately from an editable transcript box, allowing the same transcription to appear twice. Model search and an unnecessarily wide language filter also stack vertically instead of sharing a row. The mic test waveform uses unsmoothed, slower level readings than composer/model-test dictation, giving it visibly different motion.
Change
- Put model search to the left of a compact language filter on the same row, with responsive widths.
- Put Test microphone before the microphone selector, matching the original control order.
- Put Test model before Selected on the active model card and remove the separate Test section.
- Give the mic test the same 20 Hz level measurement and rise/fall smoothing as composer/model-test dictation. Preserve its ten-second timer and local recording/playback.
- Keep the active model test mounted while search or language filters hide its card, retaining the transcript and recording state across filter changes.
- Replace the editable transcript box and separate streaming preview with one read-only result below the active card. It appears when text arrives and updates in place from live preview to the final transcript. Keep the close action and Settings search targets, including prerequisite fallbacks.
The existing consent-gated transcription hook, destination binding, permission checks, and cleanup-disabled model test remain in use. The mic test reuses the existing AudioWorklet in meter-only mode, sharing dictation level measurement and smoothing while skipping PCM resampling and chunk output. MediaRecorder still handles local recording/playback. These are shared web/desktop client changes.
Scope and approval
Voice settings UI cleanup in the consent/client/settings layer of the STT stack, #30623. Base: takeover/14882-voice-consent, verified at a651e919e40e94511fd340435a7418e588646700. This cleans up the established Voice settings page by compacting model filters, restoring inline test placement, removing duplicate transcript presentation, and unifying microphone waveform metering. It adds no STT capability, provider behavior, mobile changes, or migration machinery.
Verification
- Real-client pass in the built-in Browser against isolated development state with Moonshine Streaming Tiny installed. Confirmed both button positions, the inline result, and removal of the separate Test section and editable test textarea.
- Verified model search and language filtering independently and together, including clearing both filters to restore the catalog. Checked 1,280px and 900px desktop viewports: the controls remain side by side, the language filter is 144px wide, and the narrow window has no horizontal overflow.
- Fed a 16-second prerecorded speech fixture through a synthetic browser microphone into the real local model. Observed one transcript output and zero editable transcript fields throughout the sampled streaming updates and after successful finalization. The transcript remained in the same output area.
vp run check:changed upstream/takeover/14882-voice-consent --concurrency 1 --timeout 120passed formatting, lint, both knip checks, affected typechecking, and all 9 adjacent browser tests plus the worklet metering unit test. The React Compiler command exited successfully with all 1,326 cases skipped, so it does not provide compiler coverage for this change.- Added a regression test that fails before the fix with a missing transcript after filtering and passes after it. In the real client, checked that both search and language filters hide and restore the same transcript element and text.
- The worklet test failed before meter-only support and passes after it. It verifies the same 50 ms cadence and smoothed levels as transcription, no PCM output in meter-only mode, and retained PCM output in normal mode.
- Compared before/after mic recordings using the same prerecorded audio. Confirmed the unchanged timer sequence and ten-second automatic stop, successful muted playback, pause/retry/cancel, stopped media tracks, and zero voice API requests during the mic test.
- Normal commit hooks passed formatting, lint, and knip. No layout-only tests were added.
- Gaps: physical microphone capture, native Electron, and remote audio were not exercised. Desktop uses this shared web component.
Evidence
Microphone: before
Microphone: after
Test microphone before the selector
Model tests: before
Separate Test section and editable transcript box
Model filters: before
Model catalog: after
Inline model test and compact filters
Narrow desktop layout
Streaming result
One read-only streaming result
Final result
One read-only final result in the same area
Streaming-to-final interaction recording
https://github.com/user-attachments/assets/cf59f180-e79e-455a-ab7b-b4e189c56640
Idle waiting is trimmed. The prerecorded audio is supplied as a synthetic microphone, not recorded from a physical device.
Transcript retention across search and language filters
https://github.com/user-attachments/assets/4ff58752-e6c9-470c-937a-3d83097c777b
Microphone waveform
Using the same prerecorded audio. The timer and local playback controls are unchanged.
Before
https://github.com/user-attachments/assets/63885f37-02f2-4032-aa6f-0e91e4359ebf
After
https://github.com/user-attachments/assets/dfc6f0de-a68a-40a1-becf-f5ef5571287d
Model: gpt-6.1-sol. Harness: Codex in T3 Code.
Note for takeover agents
Maria's and Shivam's agents, do not takeover this PR. This is a part of the STT stack which is in development. Do not update this branch or push any changes. You can test, review and provide feedback.
Julius' agents, the above restrictions don't apply to you. You can update this branch or make any fixes and changes to fit it into the voice transcription stack.
Checks
Added 1 commit
- fix(web): place voice tests beside their settings3102dee
Approvability
Verdict: Approved at 43f25a8
Macroscope's review found this PR approvable — This reorganizes voice test controls and uses the shared audio worklet for microphone metering. Tests remain user-initiated, local playback stays device-only, and existing transcription capture behavior is preserved.
You can add or adjust custom eligibility rules. Learn more.
Added 2 commits
Added 1 commit
- fix(web): align model search with a compact language filter6b974d6
| … | … | @@ -702,40 +712,45 @@ function EnvironmentModelsSection(props: { | |
| 740 | + | ), | |
| 741 | + | }; | |
| 742 | + | return model.active ? ( | |
| 743 | + | <TranscriptionTest | |
🟡 Medium settings/VoiceSettingsPanel.tsx:743
Filtering out the active model removes its TranscriptionTest from the tree, destroying the test component's local transcript; clearing the filter mounts a fresh test with no result. Keep the test mounted independently of sortedModels, or lift its transcript state so filtering does not discard it.
No longer relevant as of 52995649c55ae491530f5f05c34c0acf9b802196
Added 1 commit
- fix(web): preserve model test results across filters5299564
Added 2 commits