Skip to content

Add multi-LLM fallback support (Pixtral / Mistral / Groq) and UI settings#4

Merged
Lzxpan merged 1 commit into
masterfrom
codex/analyze-proposed-modifications-and-features
Mar 14, 2026
Merged

Add multi-LLM fallback support (Pixtral / Mistral / Groq) and UI settings#4
Lzxpan merged 1 commit into
masterfrom
codex/analyze-proposed-modifications-and-features

Conversation

@Lzxpan

@Lzxpan Lzxpan commented Mar 14, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Add support for multiple LLM providers and automatic fallback so OCR translations can continue when one provider is rate-limited or unavailable.
  • Expose provider-specific API keys and model selections in the UI and persist them in user settings.
  • Provide OpenAI-compatible clients to reach non-Gemini providers (including local vLLM endpoints) and unify error/retry handling.
  • Improve UX on window close by prompting to exit or minimize to tray.

Description

  • Added new user settings and defaults for ApiKey_Pixtral, ModelName_Pixtral, ApiKey_MistralPixtral, ModelName_MistralPixtral, ApiKey_Llama4, and ModelName_Llama4 and updated App.config, Settings.settings, and Settings.Designer.cs to persist them.
  • Extended Form1 to add model combo boxes and API key textboxes for Pixtral / Mistral / Llama4, initialize option lists, update link labels, and read/save those settings on load/close.
  • Reworked close handling in Form1_FormClosing to prompt the user to exit, minimize to tray, or cancel.
  • Introduced a fallback orchestration in Form1 using BuildLlmCredentials(), TranslateTextWithFallbackAsync(), and TranslateImageWithFallbackAsync() to attempt multiple configured providers in order and switch on quota/rate-limit or retryable network errors.
  • Added LlmClients.cs implementing LlmProvider, LlmCredential, LlmErrorPolicy, and OpenAiCompatibleClient with helpers to call OpenAI-compatible chat endpoints and to post image data as data-URI for OCR+translation.
  • Updated HandleCapturedImage to call the new fallback methods and update UI/token usage handling accordingly.
  • Included the new LlmClients.cs in the project file (ScreenOCRTranslator.csproj).

Testing

  • No automated tests were executed for this change.

Codex Task

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3857a1a79a

ℹ️ 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".

Comment thread Form1.cs
Comment on lines +851 to +852
if (cmbModel_Pixtral.SelectedItem != null)
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip local Pixtral fallback unless user configured it

BuildLlmCredentials() currently adds the local Pixtral endpoint whenever cmbModel_Pixtral.SelectedItem is set, and Form1_Load always selects an item by default, so an unconfigured http://127.0.0.1:8000/v1 provider is injected for all users. In the common setup without a local vLLM server, this implicit step fails before later providers are reached, which can prevent configured Mistral/Groq fallbacks from being attempted after a Gemini quota/rate-limit event.

Useful? React with 👍 / 👎.

Comment thread LlmClients.cs
Comment on lines +141 to +145
catch (Exception ex)
{
return new GeminiResult
{
HttpStatus = 0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Let network errors bubble so fallback can try next provider

PostChatCompletion() swallows transport exceptions and returns a synthetic GeminiResult (HttpStatus = 0) instead of throwing. The fallback orchestration in TranslateTextWithFallbackAsync()/TranslateImageWithFallbackAsync() only switches providers for network failures in their catch (Exception) branch, so these wrapped errors are treated as terminal non-quota failures and the chain stops early. A transient connection failure on one OpenAI-compatible provider can therefore block trying later configured providers.

Useful? React with 👍 / 👎.

@Lzxpan Lzxpan merged commit 178cd5e into master Mar 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant