Summary
Environment
- Version: 1.0.39+124 (main @ 4401c41)
- Platform: Android
- Provider: Gemini (API key), audio-capable model
- Settings > Speech transcription > "Use local speech to text": OFF
Summary
With local STT disabled, the quick recording (long-press on the AI core button) produces no transcript at all. The recorded audio is written to a temp WAV and then discarded without ever being sent to the configured LLM. The user only sees the "no speech detected" toast.
The cloud transcription code itself looks complete and correct — it is simply never invoked from anywhere in the app.
Steps to reproduce
- Configure a provider whose model accepts audio input (e.g. Gemini Flash).
- Settings > Speech transcription > turn OFF "Use local speech to text".
- Long-press the center AI button, speak, release on an action.
Expected: the recording is transcribed by the configured model and opens the entry dialog as draft text.
Actual: no text appears during or after recording; a "no speech detected" toast is shown and the WAV is dropped.
Root cause
In lib/main.dart, _stopRecording() branches on isUsingLocalModel():
- local branch: calls
SpeechTranscriptionService.transcribeSamples(samples) and assigns the result to _quickTranscribedText (~line 1362).
- cloud branch: saves the PCM buffer as a WAV and only stores the path in
_quickAudioPath (~line 1375). No transcription call.
_quickTranscribedText can never be populated in cloud mode, because streaming transcription is local-only (supportsStreamingTranscription() returns false when not using the local model). So in _handleShortcutSelect() the empty-transcript branch is always taken and only shows speechNoResult (~line 1405), after which _quickAudioPath is set back to null and the file is never used.
Grepping the repo, transcribeFile, transcribeFileWithMetadata, transcribeSamplesWithMetadata and the private _transcribeFileWithCloud / _transcribeSamplesWithCloud in lib/data/services/speech_transcription_service.dart have no callers outside that file. The cloud path is effectively dead code.
Suggested fix
In the cloud branch of _stopRecording(), await SpeechTranscriptionService.instance.transcribeFile(wavPath) (or transcribeSamples(samples), which routes to the cloud implementation automatically) and assign the result to _quickTranscribedText, mirroring the local branch.
One thing to watch if the file-based variant is used: AssetSafetyService._inspectAudio() derives the duration from a numeric suffix in the file name. The quick recording is named quick_audio_<epoch_ms>.wav, so the epoch timestamp would be parsed as the duration in seconds and exceed maxAudioSecondsForAutoTranscribe (300), making the asset fail the safety check. The samples-based variant avoids the inspection entirely.
Impact
This makes voice input unusable for any language the bundled SenseVoice model does not support (it covers zh/en/ja/ko/yue). German speech, for example, is transcribed into English-sounding nonsense in local mode, and disabling local STT yields nothing at all — so there is currently no working path for those users.
Steps to reproduce
- Configure a provider whose model accepts audio input (e.g. Gemini Flash).
- Settings > Speech transcription > turn OFF "Use local speech to text".
- Long-press the center AI button, speak, release on an action.
Expected behavior
Expected: the recording is transcribed by the configured model and opens the entry dialog as draft text.
Actual behavior
Actual: no text appears during or after recording; a "no speech detected" toast is shown and the WAV is dropped.
Platform
Android
Memex version or commit
No response
Logs, screenshots, or recordings
Privacy check
Summary
Environment
Summary
With local STT disabled, the quick recording (long-press on the AI core button) produces no transcript at all. The recorded audio is written to a temp WAV and then discarded without ever being sent to the configured LLM. The user only sees the "no speech detected" toast.
The cloud transcription code itself looks complete and correct — it is simply never invoked from anywhere in the app.
Steps to reproduce
Expected: the recording is transcribed by the configured model and opens the entry dialog as draft text.
Actual: no text appears during or after recording; a "no speech detected" toast is shown and the WAV is dropped.
Root cause
In
lib/main.dart,_stopRecording()branches onisUsingLocalModel():SpeechTranscriptionService.transcribeSamples(samples)and assigns the result to_quickTranscribedText(~line 1362)._quickAudioPath(~line 1375). No transcription call._quickTranscribedTextcan never be populated in cloud mode, because streaming transcription is local-only (supportsStreamingTranscription()returns false when not using the local model). So in_handleShortcutSelect()the empty-transcript branch is always taken and only showsspeechNoResult(~line 1405), after which_quickAudioPathis set back to null and the file is never used.Grepping the repo,
transcribeFile,transcribeFileWithMetadata,transcribeSamplesWithMetadataand the private_transcribeFileWithCloud/_transcribeSamplesWithCloudinlib/data/services/speech_transcription_service.darthave no callers outside that file. The cloud path is effectively dead code.Suggested fix
In the cloud branch of
_stopRecording(), awaitSpeechTranscriptionService.instance.transcribeFile(wavPath)(ortranscribeSamples(samples), which routes to the cloud implementation automatically) and assign the result to_quickTranscribedText, mirroring the local branch.One thing to watch if the file-based variant is used:
AssetSafetyService._inspectAudio()derives the duration from a numeric suffix in the file name. The quick recording is namedquick_audio_<epoch_ms>.wav, so the epoch timestamp would be parsed as the duration in seconds and exceedmaxAudioSecondsForAutoTranscribe(300), making the asset fail the safety check. The samples-based variant avoids the inspection entirely.Impact
This makes voice input unusable for any language the bundled SenseVoice model does not support (it covers zh/en/ja/ko/yue). German speech, for example, is transcribed into English-sounding nonsense in local mode, and disabling local STT yields nothing at all — so there is currently no working path for those users.
Steps to reproduce
Expected behavior
Expected: the recording is transcribed by the configured model and opens the entry dialog as draft text.
Actual behavior
Actual: no text appears during or after recording; a "no speech detected" toast is shown and the WAV is dropped.
Platform
Android
Memex version or commit
No response
Logs, screenshots, or recordings
Privacy check