Repository navigation
fix(mobile): pick a cloud dictation model from the phone - #31221
Conversation
The dictation setup sheet and Voice settings showed OpenAI models as read-only text, so a host that lists only cloud models (Windows orca serve, managed SSH or WSL servers) left the phone with nothing to pick. A ready cloud row is now selectable through the same speech.dictation.setup modelId write as a downloaded model; a cloud row without a key says to add it on the paired computer instead of "Set up on desktop". Refs #31174 Reported-by: delorean2020 (@delorean2020)
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 8 minutes. View limit details
📝 Walkthrough
Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
🧹 Nitpick comments: 1
mobile/src/components/MobileDictationSetupSheet.tsx: 1
152-181: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd interface tests for
MobileDictationSetupSheet.The current tests render only
VoiceModelList. They do not renderMobileDictationSetupSheetor invoke its ready-row handler. The helper and RPC-wrapper tests also cannot detect a setup-sheet regression that changes theUse/In use/API-key UI or the handler arguments.Add a focused setup-sheet test that covers the three cloud-row states and asserts that pressing
Usepasses{ enabled: true, modelId }tosetDictationConfig. The existing RPC-wrapper test can continue to verify thespeech.dictation.setupmethod.Suggested fix
+++ b/mobile/src/components/MobileDictationSetupSheet.test.tsx @@ +describe('MobileDictationSetupSheet cloud models', () => { + it('renders Use and sends the selected model payload', async () => { + const ready = cloud('openai-gpt-4o-mini-transcribe', 'ready') + const { root } = await renderSheet(setup({ models: [ready] })) + + expect(texts(root)).toContain('Use') + await act(async () => root.findAll(isPressable)[0].props.onPress()) + + expect(setDictationConfig).toHaveBeenCalledWith(client, { + enabled: true, + modelId: ready.id + }) + }) + + it('renders In use for the selected cloud model', async () => { + const ready = cloud('openai-gpt-4o-mini-transcribe', 'ready') + const { root } = await renderSheet(setup({ models: [ready], selectedModelId: ready.id })) + + expect(texts(root)).toContain('In use') + expect(root.findAll(isPressable)).toHaveLength(0) + }) + + it('renders the API-key message without an action', async () => { + const { root } = await renderSheet( + setup({ models: [cloud('openai-gpt-4o-transcribe', 'not-downloaded')] }) + ) + + expect(texts(root)).toContain(CLOUD_MODEL_NEEDS_KEY) + expect(root.findAll(isPressable)).toHaveLength(0) + }) +})
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
11fd4f48-edf0-4df1-a574-8ea456c109e9
📒 Files selected for processing: 1
mobile/src/components/voice-model-list-cloud-models.test.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.
…; button roles and labels
ELI5
On the phone, the voice dictation setup lists speech models. Cloud models (OpenAI) were shown as plain text you couldn't tap. That's fine when the computer also has on-device models to pick. But some hosts now offer only cloud models: Windows
orca serveand managed SSH or WSL servers. On those, there was nothing to choose, so dictation could never be set up from the phone. Now a ready cloud model has a Use button, just like a downloaded model.What Changed
Before:
After:
speech.dictation.setup { enabled, modelId }write a downloaded model uses.How it works: one small function,
dictationModelRowActioninmobile/src/dictation/mobile-dictation-setup.ts, decides what each row offers: in use, use, download, downloading, or "needs API key". BothMobileDictationSetupSheet.tsxandVoiceModelList.tsxrender from it, so the two lists can't drift apart again.Why
speech.dictation.setup:configure()only checks that the id is in the catalog. They also report an OpenAI model asreadywhen a key is stored. So this needs no protocol change, and a new phone can select a cloud model on any host version.Linked Issue
Refs #31174. Thanks to @delorean2020 for the report that led here.
This is a follow-up to #31217 (speech on headless servers), which makes these cloud-only hosts list their cloud models honestly.
Visual Proof
No screenshots. The change is the button and text on existing rows, using the existing Use button, In use tag and state text. It's covered by a render test that checks the button, the tag and the text. No new styles or layout.
Testing
Tests:
mobile/src/components/voice-model-list-cloud-models.test.tsx:dictationModelRowActioncases inmobile-dictation-setup.test.ts.Checks run locally:
vitestforsrc/dictation,src/settings,src/componentsand the session sheetstscpnpm tcand the ratchetsNot checked on a device: I haven't run this on a real phone against a cloud-only host.
Review
gpt-6.1-sol, high): no findings.Agent skill upstream boundary
Notes
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)