Repository navigation
Conversation
…ettings UI Phase 1 of configurable AI provider: users can add, edit, activate, and delete AI provider configs from Account Settings. API keys are encrypted via Rails encrypts. First config auto-activates.
…yService Replace raw Net::HTTP calls with RubyLLM.context for per-request API key isolation. Service now accepts account: param and reads the active AI provider config. Uses fast_model for summaries.
…concern Extract AiProviderChat concern for per-request RubyLLM context setup. Convert AiSummaryService, BranchNameGenerator, PrContentGenerator, and SimpleCodeFixApplier from raw Net::HTTP to RubyLLM. All services now accept account: param and read the active provider config. Delete all duplicated HTTP client code from AI services.
Account#ai_provider_config falls back to ENV keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY) when no database config exists. Updated performance view to link to account settings instead of showing raw ENV key instructions. Updated all GitHub service specs to use account-based AI provider mocking.
… interface Replace raw Anthropic HTTP stubs with RubyLLM ai_chat mocks. Pass account: to constructor matching the refactored service interface.
- Add Account Settings link to admin sidebar navigation - Fix unclosed div tag that prevented AI provider form submission - Add searchable model select dropdowns powered by RubyLLM registry - Add models API endpoint to serve provider-specific model lists - Fix nil start_line crash in normalize_source_context helper - Remove duplicate notification preferences card from account settings
- Remove hardcoded encryption key fallbacks; require ENV vars in production and provide clearly-marked dev defaults - Delete stale AiSummaryService Minitest file (replaced by RSpec suite using the new account-based interface) - Add ai_provider_configs to SUPER_ADMIN_WRITABLE_CONTROLLERS so super admins can manage provider configs on viewed accounts
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.
Add Multi-Provider AI Configuration
Summary
Adds per-account AI provider configuration, letting each account choose their own AI provider (Anthropic, OpenAI, Google Gemini, etc.) and model for the AI-powered features (error summaries, performance summaries, PR content generation, branch naming, code fix application). Replaces the hardcoded
claude-haiku-4-5/ANTHROPIC_API_KEY-only integration with a pluggable, DB-backed config layered over a unified RubyLLM interface.Deployments that set
ANTHROPIC_API_KEY(or any supported provider's ENV var) continue to work unchanged — accounts without an explicit config fall back to ENV automatically.Motivation
Screenshots
What's Included
New
AiProviderConfigmodel (account_id,provider,model, encryptedapi_key,active) with one active config per account enforced viaactivate!./account/settings/ai_provider_configs(create, update, destroy, activate, models) withAiProviderConfigsController.ai_provider_form_controller.js) with dynamic model list fetched per provider, search/filter, masked key input, loading and failure states.AiProviderChat— one place where every AI service acquires a configuredRubyLLMchat instance.create_ai_provider_configs— additive only, with FK + index onaccount_id.Changed
AiSummaryService,AiPerformanceSummaryService,Github::BranchNameGenerator,Github::PrContentGenerator,Github::SimpleCodeFixApplier— all now takeaccount:and delegate provider/key resolution toAiProviderChat.Account#ai_provider_configreturns the persisted active config or an ENV-backed transient config if none exists.active_record_encryption.rbinitializer now ENV-only, fails fast in production when keys missing (required sinceAiProviderConfig#api_keyis encrypted).SUPER_ADMIN_WRITABLE_CONTROLLERSincludesai_provider_configsso super admins can manage provider configs while viewing another account.Dependencies
ruby_llm1.14.1 (+ transitive gems inGemfile.lock).Backwards Compatibility
ANTHROPIC_API_KEY) continues to work via theAccount#ai_provider_configfallback.AiSummaryJob#performsignature unchanged — in-flight jobs from prior code continue to succeed.encrypts), so ENV vars need to be set only before creating the firstAiProviderConfig.Deployment Notes
Before merging, production needs the three Active Record encryption ENV vars:
Generate with
bin/rails db:encryption:init. The initializer raises on boot in production if any are missing.Testing
ai_summary_service_test.rbdeleted — superseded by RSpec).Test Plan
bundle exec rspecpassesbundle exec rails testpassesANTHROPIC_API_KEY— AI summary generates without any DB config