Skip to content

OpenRouter provider, latency fixes, and permission hardening#22

Open
christmasday wants to merge 3 commits into
TechyCSR:mainfrom
christmasday:main
Open

OpenRouter provider, latency fixes, and permission hardening#22
christmasday wants to merge 3 commits into
TechyCSR:mainfrom
christmasday:main

Conversation

@christmasday

Copy link
Copy Markdown

Summary

Adds OpenRouter as a second LLM provider alongside Gemini, with full provider routing throughout the app. Onboarding and settings UI now include provider choice. Also includes performance improvements and stability hardening.

OpenRouter Provider

  • New _openrouter* methods in LLMService for image/text/transcription processing via raw HTTPS (OpenAI-compatible API)
  • Provider routing guards in processImageWithSkill, processTextWithSkill, processTranscriptionWithIntelligentResponse, testConnection, getStats, updateApiKey
  • Onboarding wizard (step 2): LLM provider choice (Gemini / OpenRouter) with conditional key and model fields
  • Settings UI: LLM Provider dropdown, show/hide Gemini or OpenRouter fields
  • Default model: openrouter/free (auto-routes to free vision-capable models)
  • first-run.js: getStatus() returns llmProvider, openrouterConfigured, openrouterModel; needsOnboarding() checks both providers

Performance

  • Parallelized Gemini retry (_raceGeminiMethods): SDK + HTTPS methods race simultaneously instead of sequential fallback — first success wins, zero latency penalty on happy path
  • Reduced config defaults: timeout 60000→30000ms, maxRetries 3→1
  • Increased HTTPS maxSockets: 1→4 for concurrent connections
  • Removed artificial delays:
    • 500ms → 50ms in main.js (lines 366, 583)
    • 200ms window rendering delay after expansion in llm-response-window.js
    • 100ms setTimeout in display state verification
    • 200ms setTimeout before window resize request
    • 50ms DOM-ready delay before displaying response

Stability / Crashes

  • Screen recording crash (macOS 14+): try/catch around desktopCapturer.getSources() + systemPreferences.getMediaAccessStatus(screen) pre-check with clear error message if permission is denied
  • Microphone crash: _ensureMicrophonePermission() using systemPreferences.askForMediaAccess(microphone) guards all three recording entry points (IPC handle, IPC listener, Alt+R shortcut)
  • Destroyed window: isDestroyed() guard in showLLMLoading() prevents sending IPC to a destroyed window
  • macOS permission descriptions (NSMicrophoneUsageDescription, NSScreenCaptureDescription, NSCameraUsageDescription) in build.extendInfo

Adds OpenRouter as a second LLM provider alongside Gemini, with full
routing in the LLM service, onboarding wizard, and settings UI.

Key changes:
- New _openrouter* methods in LLMService for image/text/transcription
  processing, using raw HTTPS (OpenAI-compatible API)
- Provider routing guards in all public processing methods
- Onboarding wizard: LLM provider choice step with conditional
  Gemini/OpenRouter key fields, summary display
- Settings UI: provider dropdown with conditional field groups
- first-run.js: getStatus() returns llmProvider, openrouterConfigured,
  openrouterModel; needsOnboarding() checks both providers
- macOS permission descriptions (NSMicrophoneUsageDescription,
  NSScreenCaptureDescription, NSCameraUsageDescription)

Performance improvements:
- Parallelized dual-method retry (_raceGeminiMethods) — race SDK vs HTTPS
  instead of sequential fallback
- Reduced config defaults: timeout 60000→30000ms, maxRetries 3→1
- Increased https maxSockets 1→4
- Removed 500ms artificial delays in main.js (lines 366, 583 -> 50ms)
- Removed 200ms window rendering delays in llm-response-window.js
- Removed 100ms display verification setTimeout
- Removed 200ms resize request setTimeout

Stability fixes:
- try-catch around desktopCapturer.getSources() to prevent macOS 14+
  crash when screen recording permission is missing
- systemPreferences.getMediaAccessStatus('screen') pre-check with clear
  error message
- _ensureMicrophonePermission() using askForMediaAccess('microphone')
  guards all recording entry points
- isDestroyed() guard in showLLMLoading() to prevent sending IPC to a
  destroyed window
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

@christmasday is attempting to deploy a commit to the csrsoftwares' projects Team on Vercel.

A member of the Team first needs to authorize it.

Promise.allSettled waited for ALL promises to settle before returning
the fastest result. This caused the user to wait for the slowest method
(e.g. 30s HTTPS timeout) even when the SDK method succeeded in 2s.

Promise.any returns as soon as the FIRST method fulfills, so there is
zero latency penalty from the slower method on the happy path.
BREAKING: The previous single-skill (DSA) system is replaced by three
distinct modes that users can navigate via keyboard shortcuts or settings.

New skills:
- General: versatile assistant for a wide variety of questions
- Coding: programming-focused mode with language enforcement
- Meeting: passive listener that detects questions during meetings

Changes:
- prompts/: replaced dsa.md + unused programming.md with general.md,
  coding.md, meeting.md
- prompt-loader.js:
  - skillsRequiringProgrammingLanguage: dsa -> coding
  - Loads all three .md prompts (drops the dsa-only filter)
  - normalizeSkillName maps old names to new skills
  - getAvailableSkills returns [general, coding, meeting]
- main.js: default skill 'general'; navigateSkill cycles 3 skills;
  programming language gates on 'coding'
- session.manager.js: default skill 'general'
- src/ui/main-window.js: skill names, icons, language selector
  visibility (shown only in Coding mode), click handler cycles forward
- settings.html: dropdown options for three skills
- src/ui/chat-window.js: updated skill icon map
- src/services/llm.service.js: formatImageInstruction, formatUserMessage,
  getIntelligentTranscriptionPrompt updated per mode; fallback responses and
  skill keywords updated for new skills
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