fix(ios): auto-fallback from PCM to MP3 for ElevenLabs TTS#30885
fix(ios): auto-fallback from PCM to MP3 for ElevenLabs TTS#30885leepokai wants to merge 2 commits intoopenclaw:mainfrom
Conversation
The default output format pcm_44100 requires an ElevenLabs Pro tier subscription. Users on free or starter plans get a silent 403 failure and hear no audio. Instead of hardcoding mp3, keep pcm_44100 as the default (better quality for Pro users) but remember the failure: when a PCM request is rejected, set pcmFormatUnavailable and use mp3_44100_128 for all subsequent requests in the session. The flag resets on config reload so it re-probes after reconnection. Also standardize the MP3 fallback format from mp3_44100 to mp3_44100_128 for consistent bitrate. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbc26ef9f3
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.gatewayTalkDefaultModelId = nil | ||
| self.gatewayTalkApiKeyConfigured = false | ||
| self.gatewayTalkConfigLoaded = false | ||
| self.pcmFormatUnavailable = false |
There was a problem hiding this comment.
Reset PCM fallback state on successful config reloads
pcmFormatUnavailable is only cleared in the catch branch of reloadConfig(), so a normal reconnect/config refresh leaves the flag stuck once it has been set. After a single PCM failure, subsequent sessions in the same app process will keep defaulting to MP3 instead of re-probing PCM, which contradicts the intended reconnect behavior and causes avoidable quality/latency degradation for users who can use PCM.
Useful? React with 👍 / 👎.
| var playback = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate) | ||
| if !playback.finished, playback.interruptedAt == nil { | ||
| self.logger.warning("pcm playback failed; retrying mp3") | ||
| self.pcmFormatUnavailable = true |
There was a problem hiding this comment.
Invalidate incremental context after marking PCM unavailable
When incremental playback hits a PCM failure, this sets pcmFormatUnavailable but does not refresh the cached IncrementalSpeechContext; updateIncrementalContextIfNeeded() reuses that context while the directive is unchanged, so context.outputFormat can remain PCM for later segments. In cases where prefetched MP3 audio is unavailable, speakIncrementalSegment will still issue a new PCM synthesis request and then retry MP3, so the new “skip PCM after first failure” optimization is not consistently applied in incremental mode.
Useful? React with 👍 / 👎.
Greptile SummaryThis PR implements a session-level fallback from PCM to MP3 for ElevenLabs TTS when the API rejects the PCM format (typically due to subscription tier limitations). The implementation correctly adds a Critical issue found: The flag is only reset in the Confidence Score: 2/5
Last reviewed commit: fbc26ef |
| self.gatewayTalkDefaultModelId = nil | ||
| self.gatewayTalkApiKeyConfigured = false | ||
| self.gatewayTalkConfigLoaded = false | ||
| self.pcmFormatUnavailable = false |
There was a problem hiding this comment.
The flag is only reset in the catch block when config loading fails. It won't reset on successful reconnect, breaking the re-probe behavior described in the PR. Move this to the beginning of reloadConfig() (before line 1935) so it resets on every config reload.
| self.pcmFormatUnavailable = false | |
| guard let gateway else { return } | |
| self.pcmFormatUnavailable = false | |
| do { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/ios/Sources/Voice/TalkModeManager.swift
Line: 2006
Comment:
The flag is only reset in the catch block when config loading fails. It won't reset on successful reconnect, breaking the re-probe behavior described in the PR. Move this to the beginning of `reloadConfig()` (before line 1935) so it resets on every config reload.
```suggestion
guard let gateway else { return }
self.pcmFormatUnavailable = false
do {
```
How can I resolve this? If you propose a fix, please make it concise.Merged via /review-pr -> /prepare-pr -> /merge-pr. Prepared head SHA: f77e3d7 Co-authored-by: mbelinky <[email protected]> Co-authored-by: mbelinky <[email protected]> Reviewed-by: @mbelinky
…law#33032) Merged via /review-pr -> /prepare-pr -> /merge-pr. Prepared head SHA: f77e3d7 Co-authored-by: mbelinky <[email protected]> Co-authored-by: mbelinky <[email protected]> Reviewed-by: @mbelinky
Summary
pcm_44100as the default TTS output format (better quality/lower latency for Pro users)subscription_required), automatically fall back tomp3_44100_128and setpcmFormatUnavailableto skip PCM for all subsequent requests in the sessionreloadConfig()(reconnect/new session) so it re-probes the APImp3_44100tomp3_44100_128for consistent bitrateRoot cause
pcm_44100output format requires an ElevenLabs Pro tier subscription. Users on free or starter plans receive a silent HTTP 403 error, causing TTS to fail with no audio output. The existing PCM-to-MP3 retry path fired on every segment without remembering the failure, wasting an API call each time.Test plan
outputFormatin talk config overrides the default (both PCM and MP3)🤖 Generated with Claude Code