Skip to content

fix(desktop): align transcription language options#7209

Open
waffensam wants to merge 2 commits intoBasedHardware:mainfrom
waffensam:codex/desktop-language-alignment
Open

fix(desktop): align transcription language options#7209
waffensam wants to merge 2 commits intoBasedHardware:mainfrom
waffensam:codex/desktop-language-alignment

Conversation

@waffensam
Copy link
Copy Markdown
Contributor

Summary

  • Align the desktop single-language picker with the backend-approved Deepgram Nova-3 language codes, including Chinese variants and other languages that were already supported by /v4/listen.
  • Normalize legacy/backend/user-entered aliases such as chinese, zh, 中文, and br into language codes accepted by the streaming endpoint, and write normalized persisted values back once read.
  • Keep auto-detect limited to languages supported by Deepgram Nova-3 multi-language mode, so Chinese stays in single-language mode when synced from backend settings or set through chat tools.

Test plan

  • swift test --package-path Desktop --filter AssistantSettingsLanguageTests

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 8, 2026

Greptile Summary

This PR aligns the desktop transcription language picker with backend-approved Deepgram Nova-3 language codes, adding Chinese variants (zh-CN/HK/TW) and many additional languages, and introduces normalizeTranscriptionLanguageCode to canonicalize legacy aliases such as chinese, zh, br, and Chinese-character names before they reach the streaming endpoint or get persisted.

  • AssistantSettings gains a normalizeTranscriptionLanguageCode function that maps aliases via a lookup table, then falls back to a case-insensitive match against supportedLanguages; the transcriptionLanguage getter lazily migrates any stored legacy value in place.
  • SettingsPage and ChatToolExecutor are updated to normalize at their respective call sites, and the backend-sync path now gates auto-detect on supportsAutoDetect(normalizedLanguage) so Chinese is kept in single-language mode.
  • New AssistantSettingsLanguageTests cover alias resolution, write-back migration, and multi-language gating.

Confidence Score: 4/5

Safe to merge; the normalization logic is well-covered by tests and the call-site changes are minimal and consistent.

The getter write-back migration fires without posting transcriptionSettingsDidChange, so any observer active at the moment of migration won't be notified. The test teardown also leaves transcriptionAutoDetect dirty on the shared singleton. Both are small issues unlikely to cause production problems, but worth tidying before merge.

The write-back path in AssistantSettings.swift (getter) and the teardown in AssistantSettingsLanguageTests.swift are the only spots that could use a quick fix.

Important Files Changed

Filename Overview
desktop/Desktop/Sources/ProactiveAssistants/Services/AssistantSettings.swift Core change — expands supported language list, adds normalizeTranscriptionLanguageCode for alias mapping, refactors effectiveTranscriptionLanguage and supportsAutoDetect. Getter write-back migration omits the settings-change notification.
desktop/Desktop/Sources/MainWindow/Pages/SettingsPage.swift Integrates normalization at the backend-sync call site and guards auto-detect mode with supportsAutoDetect; changes look correct.
desktop/Desktop/Sources/Providers/ChatToolExecutor.swift Normalizes the chat-tool-supplied language before storing, updating auto-detect, and sending to the API — correctly aligned with the new normalization flow.
desktop/Desktop/Tests/AssistantSettingsLanguageTests.swift New tests cover alias normalization and auto-detect gating, but tearDown doesn't clean up transcriptionAutoDetect, leaving the shared singleton dirty between tests.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Raw language string\n(UserDefaults / backend / chat tool)"] --> B["normalizeTranscriptionLanguageCode()"]
    B --> C{In alias\ndictionary?}
    C -- Yes --> D["Return canonical code\n(e.g. 'zh-CN', 'pt-BR')"]
    C -- No --> E{Case-insensitive match\nin supportedLanguages?}
    E -- Yes --> F["Return canonical code\nfrom supportedLanguages"]
    E -- No --> G["Return underscore→dash\nnormalized value as-is"]
    D --> H["supportsAutoDetect()"]
    F --> H
    G --> H
    H --> I{In\nmultiLanguageSupported?}
    I -- Yes --> J["effectiveLanguage = 'multi'\n(auto-detect)"]
    I -- No --> K["effectiveLanguage = specific code\n(single-language mode)"]
    J --> L["/v4/listen API"]
    K --> L
Loading

Reviews (1): Last reviewed commit: "fix(desktop): align transcription langua..." | Re-trigger Greptile

Comment on lines +113 to +116
if normalized != value {
UserDefaults.standard.set(normalized, forKey: transcriptionLanguageKey)
}
return normalized
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The transcriptionLanguage getter silently writes a normalized value back to UserDefaults without posting transcriptionSettingsDidChange. Every other mutation to transcriptionLanguage goes through the setter, which always posts the notification so observers (e.g., the audio stack) can react. If an observer is active at the moment this one-time migration fires, it won't be told the value changed, leaving the streamed language code potentially stale until the next explicit set.

Suggested change
if normalized != value {
UserDefaults.standard.set(normalized, forKey: transcriptionLanguageKey)
}
return normalized
if normalized != value {
UserDefaults.standard.set(normalized, forKey: transcriptionLanguageKey)
NotificationCenter.default.post(name: .transcriptionSettingsDidChange, object: nil)
}
return normalized

Comment on lines +8 to +16
override func setUp() {
super.setUp()
UserDefaults.standard.removeObject(forKey: languageKey)
}

override func tearDown() {
UserDefaults.standard.removeObject(forKey: languageKey)
super.tearDown()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 testChineseDoesNotUseAutoDetectMultiLanguageMode writes true to AssistantSettings.shared.transcriptionAutoDetect, but tearDown only removes transcriptionLanguage from UserDefaults. The transcriptionAutoDetect key is left dirty for any subsequent test that reads effectiveTranscriptionLanguage on the shared singleton. Adding transcriptionAutoDetect removal to both setUp and tearDown keeps tests independent of execution order.

Suggested change
override func setUp() {
super.setUp()
UserDefaults.standard.removeObject(forKey: languageKey)
}
override func tearDown() {
UserDefaults.standard.removeObject(forKey: languageKey)
super.tearDown()
}
private let autoDetectKey = "transcriptionAutoDetect"
override func setUp() {
super.setUp()
UserDefaults.standard.removeObject(forKey: languageKey)
UserDefaults.standard.removeObject(forKey: autoDetectKey)
}
override func tearDown() {
UserDefaults.standard.removeObject(forKey: languageKey)
UserDefaults.standard.removeObject(forKey: autoDetectKey)
super.tearDown()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant