fix(ai): give text analysis a real multi-vendor fallback chain - #238
Merged
Conversation
llm-analysis.js and aiAnalysisService.js each constructed their own OpenAI client, hardcoded model: 'gpt-4', and threw/skipped outright whenever OPENAI_API_KEY was unset — a single vendor, single model, with no recovery path. The moment OpenAI has a billing hiccup, an outage, or retires gpt-4, every text-analysis feature in this app goes dead until someone notices and redeploys. backend/lib/aiChain.js gives both services a real chain via ai-kit (Groq -> OpenRouter free tier, same package already adopted fleet-wide for this exact failure mode), plus a health tracker exposed informationally on /health (never gates the endpoint's status — a dead vendor key can't be fixed by a restart). Vision/image analysis (imageIngestionService.js, video frame analysis, openaiVisionService.ts) and Whisper audio transcription stay on OpenAI directly: ai-kit's free chain carries no vision- or audio-capable free models, so forcing those onto it would silently degrade output quality rather than provide a real fallback. Documented as a known limitation in .claude/CLAUDE.md's env var list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVwg8DKHQktxJuHeLM3xpG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
backend/services/llm-analysis.jsandbackend/services/aiAnalysisService.jseach hardcoded a single OpenAI client (model: 'gpt-4') with no fallback — threw/skipped outright ifOPENAI_API_KEYwas unset, and would go fully dead on any OpenAI outage/billing hiccup/model retirement.backend/lib/aiChain.jsgives both services a real chain viaai-kit(Groq → OpenRouter free tier), plus a health tracker exposed informationally on/health(never gates the endpoint's status).databaseController.js'sanalyzeDatabaseno longer accepts a client-suppliedmodel(gpt-4 vs gpt-3.5 was never a real fallback, just two names for the same vendor) — old clients sending it are unaffected, the field is just ignored now.Deliberately left as a documented limitation
Vision/image analysis (
imageIngestionService.js, video frame analysis,openaiVisionService.ts) and Whisper audio transcription stay on OpenAI directly —ai-kit's free chain has no vision- or audio-capable free models, so forcing those onto it would silently degrade output quality rather than provide a real fallback. Documented in.claude/CLAUDE.md's env var list.Test plan
npm run verifygreen (format, lint 0 errors, typecheck, 46 tests, build)api.openai.comchat-completion calls outside the vision/audio paths noted above