Skip to content

feat: add VITE_ENABLED_PROVIDERS to control available AI providers#351

Open
feraudet wants to merge 3 commits intositeboon:mainfrom
feraudet:feature/enabled-providers
Open

feat: add VITE_ENABLED_PROVIDERS to control available AI providers#351
feraudet wants to merge 3 commits intositeboon:mainfrom
feraudet:feature/enabled-providers

Conversation

@feraudet
Copy link

@feraudet feraudet commented Jan 28, 2026

Summary

Implements #349 - Add VITE_ENABLED_PROVIDERS environment variable to control which AI providers are shown in the UI.

Changes

  • Add src/utils/providers.js with helper functions:
    • getEnabledProviders() - returns array of enabled providers
    • isProviderEnabled(provider) - checks if a provider is enabled
    • getDefaultProvider() - returns first enabled provider
  • Update ChatInterface.jsx to conditionally render provider buttons
  • Update Settings.jsx to conditionally render agent list items

Configuration

# Only Claude Code
VITE_ENABLED_PROVIDERS=claude

# Claude + Cursor
VITE_ENABLED_PROVIDERS=claude,cursor

# All providers (default if not set)
VITE_ENABLED_PROVIDERS=claude,cursor,codex

Test plan

  • Set VITE_ENABLED_PROVIDERS=claude - only Claude appears
  • Set VITE_ENABLED_PROVIDERS=claude,cursor - both appear
  • Remove variable - all three providers visible (default)

Closes #349

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Providers can be enabled or disabled via configuration.
    • Disabled providers are hidden from the interface and cannot be selected.
    • Persisted provider selection now falls back to an enabled provider when needed.
    • Provider visibility is applied consistently across mobile and desktop views.
    • Default provider is now determined dynamically from configuration and provider availability.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 28, 2026

Walkthrough

Adds a providers utility that reads VITE_ENABLED_PROVIDERS and exposes getEnabledProviders / isProviderEnabled / getDefaultProvider. ChatInterface and Settings use these utilities to hide disabled providers, ensure the selected/default provider is valid, and sync localStorage when falling back to a default.

Changes

Cohort / File(s) Summary
Provider utilities module
src/utils/providers.js
New module exporting getEnabledProviders(), isProviderEnabled(provider), and getDefaultProvider(). Parses VITE_ENABLED_PROVIDERS, normalizes input, and provides fallbacks (defaults to all providers, or 'claude' if parsing yields none).
Chat UI provider gating
src/components/ChatInterface.jsx
Imports provider utilities; initialization validates saved provider via isProviderEnabled() and falls back to getDefaultProvider() (updating localStorage). Provider selection buttons (Claude, Cursor, Codex) are conditionally rendered only when enabled.
Settings provider gating
src/components/Settings.jsx
Uses getDefaultProvider() for initial selected agent; agent list items for claude/cursor/codex are gated by isProviderEnabled() in both mobile and desktop layouts.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser (localStorage)
  participant Chat as ChatInterface
  participant Utils as providers.js

  Browser->>Chat: app loads / read("selectedProvider")
  Chat->>Utils: isProviderEnabled(savedProvider)
  alt savedProvider enabled
    Utils-->>Chat: true
    Chat->>Browser: use(savedProvider)
  else savedProvider missing/disabled
    Utils-->>Chat: false
    Chat->>Utils: getDefaultProvider()
    Utils-->>Chat: defaultProvider
    Chat->>Browser: write("selectedProvider", defaultProvider)
  end
  Chat->>Chat: render provider buttons gated by isProviderEnabled(...)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • viper151

Poem

🐇 I sniff the env and twitch my nose,

Which helpers hop and which one goes.
I hide the ones that shouldn't play,
Set defaults safe and tuck away.
A tiny hop — the UI knows. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: adding VITE_ENABLED_PROVIDERS environment variable to control AI provider visibility.
Linked Issues check ✅ Passed All coding requirements from issue #349 are met: environment variable support, UI gating for provider buttons and settings, default provider logic, and backwards compatibility.
Out of Scope Changes check ✅ Passed All changes directly support the linked issue objectives: new providers utility module and UI updates to ChatInterface and Settings components.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/ChatInterface.jsx`:
- Around line 1937-1940: The saved localStorage value 'selected-provider' can
remain disabled while the component state uses the fallback from
getDefaultProvider(), causing mismatches; update localStorage when initializing
provider fallback so it matches state. In the useState initializer for provider
(where saved is read and checked with isProviderEnabled), if saved is falsy or
not enabled, compute const fallback = getDefaultProvider(), call
setItem('selected-provider', fallback) and return fallback (or otherwise ensure
localStorage is written to the chosen provider) so other code reading
localStorage (headers, session loader) sees the same provider as provider state.

In `@src/utils/providers.js`:
- Around line 42-43: The isProviderEnabled function currently calls
provider.toLowerCase() unconditionally which will throw for
null/undefined/non-string inputs; update isProviderEnabled to first verify
provider is a non-empty string (e.g., typeof provider === 'string' and
provider.trim() !== '') and only then call provider.toLowerCase() before
checking getEnabledProviders().includes(...); for all other cases return false
so non-string inputs are safely handled.
🧹 Nitpick comments (1)
src/components/Settings.jsx (1)

62-62: Use a lazy initializer for the default provider.

Avoid recomputing getDefaultProvider() on every render.

♻️ Proposed change
-  const [selectedAgent, setSelectedAgent] = useState(getDefaultProvider()); // Only enabled providers
+  const [selectedAgent, setSelectedAgent] = useState(() => getDefaultProvider()); // Only enabled providers

Implements environment-based provider selection with the following:

- Add src/utils/providers.js with helper functions:
  - getEnabledProviders() - returns array of enabled providers
  - isProviderEnabled(provider) - safely checks if provider is enabled
  - getDefaultProvider() - returns first enabled provider

- Update ChatInterface.jsx:
  - Import providers utility
  - Conditionally render provider buttons based on enabled status
  - Sync localStorage when falling back to default provider

- Update Settings.jsx:
  - Import providers utility
  - Use lazy initializer for selectedAgent state
  - Conditionally render agent list items

Configuration examples:
  VITE_ENABLED_PROVIDERS=claude         # Only Claude
  VITE_ENABLED_PROVIDERS=claude,cursor  # Claude and Cursor
  (not set) = all providers enabled

Closes siteboon#349

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@feraudet feraudet force-pushed the feature/enabled-providers branch from 0326d8b to 349e5bb Compare January 28, 2026 10:42
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.

feat: add VITE_ENABLED_PROVIDERS to control available AI providers

1 participant