feat(mobile): real-time gateway dictation, voice language setting, and test field (part 1/1) - #6099
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (97 files)
Prior Findings Resolved
Previous Review Summary (commit 34d25a4)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 34d25a4)Status: 3 Issues Found | Recommendation: Address before merge Executive SummaryThe real-time gateway engine leaves one credential read unguarded, so a single rejection can poison the segment upload chain, leak files, and hang the session; two lower-risk items cover locale-sensitive search folding and a vacuous new test. Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (105 files)
Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
|
bot: Cross-platform fix. Pushed 020bf75 (kwf What changed:
|
…d test field (part 1/1) #6099
020bf75 to
9a5d4c2
Compare
|
(bot) ## Live proof (proof-only request; no code change) Ran on an unrecorded platform; the request asked for ios. This request asked for live proof of existing behaviour. There is no diff; the verify round ran the must-run scenarios and recorded the evidence below.
|
![[e1] language picker lists device-supported locales (android emulator-5554) — prior/x1.png](/home/igor_kilocode_ai/.local/share/kwf/sections/voice-language-picker-ios-proof-6099-v2-dd7f/e2e-mobile-app/prior/x1.png)
![[e1] iOS simulator, device mode: pick English (United Kingdom) en-GB, leave the screen, reopen the picker; en-GB is still checked. — e2e-mobile-app/e1.png](/home/igor_kilocode_ai/.local/share/kwf/sections/voice-language-picker-ios-proof-6099-v2-dd7f/e2e-mobile-app/e1.png)
![[e3] test voice input taps the mic with en-GB chosen (android emulator-5554) — prior/x4.png](/home/igor_kilocode_ai/.local/share/kwf/sections/voice-language-picker-ios-proof-6099-v2-dd7f/e2e-mobile-app/prior/x4.png)
![[e3] test voice input taps the mic with en-GB chosen (android emulator-5554) — scripted-shard1/e3.png](/home/igor_kilocode_ai/.local/share/kwf/sections/voice-language-picker-ios-proof-6099-v2-dd7f/e2e-mobile-app/scripted-shard1/e3.png)
![[e2] iOS simulator, device mode: pick English (United Kingdom) en-GB, leave the screen, reopen the picker; en-GB is still checked. — prior/e2-settings-picked.png](/home/igor_kilocode_ai/.local/share/kwf/sections/voice-language-picker-ios-proof-6099-v2-dd7f/e2e-mobile-app/prior/e2-settings-picked.png)
Changelog for users
Changelog for maintainers
nullor empty means Automatic, and start reconciles it against the active mode's list; the newvoice-language-pickerformSheet renders device or gateway options, anduseVoiceRecognitionLanguagesmemoizes the native locale fetch and adds a cache-invalidating retry.voiceLanguage.*andvoiceInput.test*ship in every catalog,foldForSearchis shared with the app language picker, and Androidcmn*tags normalize tozh*.SheetHeadernow uses one top-inset rule for iOS and Android: it drops thePlatformbranch and readsStatusBar.currentHeight ?? 0(an Android-only API that isundefinedon iOS);bottom-form-sheetdrops the top clearance unconditionally, whilealwaysstays a no-op on iOS because the synchronous fallback is 0; the doc comment records why Android caps its detents below the inset and the iOS sheet clears the top edge with its grabber.StatusBar.currentHeight, andsheet-header.mounted.test.tsxruns the fallback, resolved-inset, bottom-form-sheet, landscape-side-inset, and PickerSheet pass-through cases under bothiosandandroid, plus a regression asserting both platforms produce the same bottom-form-sheet style; start the review at the inset computation insheet-header.tsx.Itoı; the fold now usestoLowerCase()so language search keeps matching.topInsetassertion was vacuous; it now derives the inset wrapper from the header row and the test asserts the Done button's ancestor. Regression tests cover the rejected model read and the locale-independent fold; start the review at the guarded read, then the fold helper.E2E proof
Superseded and replaced: the earlier gateway-unreachable fault capture is replaced by the fault-injected dictation start below; the earlier single-query search check is replaced by the Turkish-locale and espanol/turkce checks; the earlier Android header-inset measurement is replaced by the repaired stack-tip opened-picker measurements in portrait and landscape below. The platform captures were recorded on Android; the repair removes the platform branch, so iOS has no separate inset path.
[p9] Gateway-mode test field appends text segment by segment before Stop (needs:recording): expected — android emulator-5554: p9-gateway-realtime.log shows the test EditText at 0 segments with 'Stop voice input'/'Listening...' (p9-listen-1), then 'Gateway transcription online Gateway transcription online' with 'Stop voice input'/'Listening...' (p9-listen-2), then 4 segments with 'Stop voice input'/'Listening...' (p9-listen-3), then 6 segments and 'Start voice input' after Stop (p9-stop), proving segment-by-segment appending before Stop; recording p9-gateway-realtime.mp4 captured for the visual reviewer.
p9-gateway-realtime.mp4.trim.mp4
[e1] Test field with no speech shows the no-speech toast and leaves the text area unchanged (needs:recording): expected — Android device mode (gateway transcription OFF) on emulator-5554: scene e1 OK shows 'No speech detected. Tap the microphone to try again.' while the field reads 'Tap the microphone and start speaking.' and the mic is back to 'Start voice input' — no UX-DEFECT (e1-behavior.log; recording e1-voice-test-nospeech.mp4).
e1-voice-test-nospeech.mp4.trim.mp4
[p9] Gateway-mode test field appends text segment by segment before Stop (needs:recording): expected — android emulator-5554: gateway transcription ON with Fake Transcribe, tapping Start voice input appended 'Gateway transcription online' segment by segment before Stop ('== t+3s 21:22:28' 3 copies, '== t+12s 21:22:49' 10 copies, 13 at Stop) and retained them after Stop (p9-final.png); recording p9-gateway-append.mp4, replay p9.replay.json re-ran as SCENE p9 OK; UX audit of the Voice input screen found no UX-DEFECT. e2e-index gap: no voice-transcription switch/test-id/fault hook is documented, only the Fake Transcribe model.
p9-gateway-append.mp4.trim.mp4
[p8] Device-mode test field appends the transcript to the text area as the user speaks (needs:recording): expected — android emulator-5606, device mode (Gateway transcription switch checked=false, Language Deutsch); a device-level fake RecognitionService (com.kilo.fakerec, installed + Settings.Secure voice_recognition_service) streamed canned partials through the app's real expo-speech-recognition path because the emulator is -no-audio. p8-run.log 'SCENE p8-listen OK' shows 'android.widget.EditText the quick brown fox jumps over tappable [82,992][998,1213]' beside 'android.widget.TextView Listening...' and 'android.widget.Button Stop voice input', and 'SCENE p8 OK' shows 'android.widget.EditText the quick…
p8-device-transcript.mp4.trim.mp4
[e1] Gateway-mode voice test field: start dictation when the stored transcription model cannot be read (fault-injected) — an error toast plus the inline status appear and the mic returns to 'Start voice… — android emulator-5554, nextjs down (fault.sh down nextjs) with gateway transcription on and 'Earlier transcript kept' in the test field: tapping Start voice input left the mic at 'Start voice input' (e1-fault.log "ASSERT HIT 'Start voice input' matches=1"), showed the inline error beside it (digest "android.widget.TextView Couldn't reach the Kilo gateway. Check your connection and try again. tappable [193,1187][792,1261]") and kept the transcript (e1-fault.log "ASSERT HIT 'Earlier transcript kept' matches=1"); recording e1-fault-model-unreadable.mp4 and screenshot e1-error-inline.png captured.
e1-fault-model-unreadable.mp4.trim.mp4
[e2] Voice language picker with the device locale set to Turkish (tr-TR): typing 'indonesian' lists Indonesian and typing 'italian' lists Italian. — Device locale tr-TR proved in out/e2-locale-evidence.log ('tr-TR' twice); out/e2-search-tr.log shows the picker search EditText 'android.widget.EditText text="indonesian"' beside result 'text="Bahasa Indonesia"' and 'text="id-ID"', and 'android.widget.EditText text="italian"' beside 'text="Italiano"' and 'text="it-IT"', with cross-checks 'absent: Italiano (correct)' and 'absent: Bahasa Indonesia (correct)'. The scripted scene aborted on a harness WebDriver stale element (out/e2e-run.log 'SCENE e2 MISS error WebDriverError: Cached elements ... do not exist in DOM anymore'), so the queries were completed via adb input + uiautomator dumps; captures e2-indonesian.png and e2-italian.png are left for the visual reviewer.
[e3] Voice language picker search regression: typing 'espanol' lists Español and 'turkce' lists Türkçe. — android emulator-5604 (en-US): e3-search-espanol.log lines 30-35 show only 'Español, es-ES'/'Español, es-US' after typing 'espanol'; e3-search.log lines 1,30-32 show 'SCENE e3-search OK' and only 'Türkçe, tr-TR' after typing 'turkce'; replay e3.replay.json; no UX-DEFECT observed.
Owner request for the stack