Skip to content

fix(translation): check active provider's token in translateAsync AI gate - #460

Merged
LeanBitLab merged 1 commit into
LeanBitLab:mainfrom
foegra:fix/translate-ai-provider-key-check
Aug 29, 2026
Merged

fix(translation): check active provider's token in translateAsync AI gate#460
LeanBitLab merged 1 commit into
LeanBitLab:mainfrom
foegra:fix/translate-ai-provider-key-check

Conversation

@foegra

@foegra foegra commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #459, refs #456.

translateAsync() gated the built-in-AI translation fallback on ProofreadService.getApiKey(), which reads only the Gemini key (KEY_API_KEY = "gemini_api_key", ProofreadService.kt:645). With provider OPENAI (custom OpenAI-compatible endpoint) or GROQ, that key is empty even when the provider is fully configured, so hasAiConfigured was false and every AI-fallback branch (lines ~414/436/449/462) short-circuited to Result.failure("Translation plugin not available") with a misleading "Offline model not downloaded" toast — before any network request was made.

Proofreading was unaffected because performAsyncOperation() performs a provider-aware check (getGroqToken() for GROQ, getHuggingFaceToken() for OPENAI). GGUF translation on the Offline flavor checks the local model path instead. The gate looks like a leftover from when Gemini was the only cloud provider.

This PR changes the gate in translateAsync() to check the active provider's token, mirroring the pattern already used by performAsyncOperation():

val hasAiConfigured = when (service.getProvider()) {
    ProofreadService.AIProvider.GEMINI -> !service.getApiKey().isNullOrBlank()
    ProofreadService.AIProvider.GROQ -> !service.getGroqToken().isNullOrBlank()
    ProofreadService.AIProvider.OPENAI -> !service.getHuggingFaceToken().isNullOrBlank()
}

Verification

  • Reproduced on v4.1.7 (standardfull), Google Pixel 10a / Android 16, provider = OpenAI-compatible custom endpoint (OpenAI /v1/chat/completions format), where the same provider+model works for proofreading:
    • Translation mode = Cloud/Local AI → toast "Offline model not downloaded", no request sent.
    • Workaround (dummy Gemini API key, provider unchanged) → translation succeeds through the OpenAI-compatible endpoint, confirming the gate was the only blocker.
  • Root cause verified against master (≈ v4.1.7): ProofreadHelper.kt:386 + ProofreadService.kt:79/645.
  • The change is a drop-in replacement at a single call site; getGroqToken() and getHuggingFaceToken() are already public methods on ProofreadService used by performAsyncOperation().

Notes

Two related cosmetic issues observed on this path (not addressed here to keep the PR minimal):

  • The AI-fallback toast (translation_plugin_fallback_to_ai, "Plugin unavailable, switching to AI") shows on every translation when the plugin isn't installed, even when the user is already in AI mode.
  • The failure toast says "Offline model not downloaded" even when an offline model was never involved.

Happy to follow up on those separately if useful.

Fixes #459
Refs #456

…gate

translateAsync() gated the built-in-AI fallback on
ProofreadService.getApiKey(), which reads only the Gemini key
(KEY_API_KEY = "gemini_api_key"). With provider OPENAI (custom
OpenAI-compatible endpoint) or GROQ, that check returned false even
when the provider was fully configured, so every AI-fallback branch
short-circuited to Result.failure("Translation plugin not available")
with a misleading "Offline model not downloaded" toast - before any
network request was made.

Proofreading was unaffected because performAsyncOperation() performs a
provider-aware token check, and GGUF translation on the offline flavor
checks getModelPath() instead.

Fix: check the active provider's token (Gemini key / Groq token /
HuggingFace token) the same way.

Fixes LeanBitLab#459
Ref LeanBitLab#456
@LeanBitLab
LeanBitLab merged commit 807944c into LeanBitLab:main Aug 29, 2026
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.

Bug: AI Translation fails with any cloud provider except Gemini — availability check reads only the Gemini API key

2 participants