Skip to content

test: add custom API provider support#5

Closed
marcveihl wants to merge 1 commit intojrenaldi79:mainfrom
marcveihl:test/custom-api-providers
Closed

test: add custom API provider support#5
marcveihl wants to merge 1 commit intojrenaldi79:mainfrom
marcveihl:test/custom-api-providers

Conversation

@marcveihl
Copy link
Copy Markdown

@marcveihl marcveihl commented Mar 12, 2026

Enable users to define custom API providers (self-hosted LLMs, proxy servers, alternative providers) via config.json and the setup wizard.

  • config.js: CRUD for customProviders in config.json
  • api-key-store.js: dynamic provider→envVar map merging built-in + custom
  • api-key-validation.js: HTTP/HTTPS validation for custom provider endpoints
  • validators.js: custom provider lookup in API key validation
  • alias-resolver.js: use dynamic env map for direct API fallback
  • Electron UI: "Add Custom Provider" form with IPC handlers
  • CLI setup: readline-based custom provider creation flow
  • .env.example: document custom provider env vars

All 1477 tests pass.

Summary by CodeRabbit

Release Notes

  • New Features
    • Support for configuring and managing custom API providers through the setup interface and CLI.
    • Ability to add, remove, and configure custom provider details including ID, name, base URL, and authentication type.
    • API key validation and persistent storage for custom providers.
    • Custom providers integrate seamlessly alongside built-in providers.

Enable users to define custom API providers (self-hosted LLMs, proxy
servers, alternative providers) via config.json and the setup wizard.

- config.js: CRUD for customProviders in config.json
- api-key-store.js: dynamic provider→envVar map merging built-in + custom
- api-key-validation.js: HTTP/HTTPS validation for custom provider endpoints
- validators.js: custom provider lookup in API key validation
- alias-resolver.js: use dynamic env map for direct API fallback
- Electron UI: "Add Custom Provider" form with IPC handlers
- CLI setup: readline-based custom provider creation flow
- .env.example: document custom provider env vars

All 1477 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 12, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b7954c3d-d534-4070-9cd3-0c3068d840fc

📥 Commits

Reviewing files that changed from the base of the PR and between 251358e and b4d98ca.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • .env.example
  • electron/ipc-setup.js
  • electron/preload-setup.js
  • electron/setup-ui-keys-script.js
  • electron/setup-ui-keys.js
  • src/sidecar/setup.js
  • src/utils/alias-resolver.js
  • src/utils/api-key-store.js
  • src/utils/api-key-validation.js
  • src/utils/config.js
  • src/utils/validators.js
  • tests/config-fallback.test.js

📝 Walkthrough

Walkthrough

This pull request introduces a custom API provider system enabling users to add, save, and manage their own API providers. The implementation spans configuration management, IPC communication, API key validation, persistent storage, and UI forms across Electron and Node.js components.

Changes

Cohort / File(s) Summary
Configuration & Storage
src/utils/config.js, src/utils/api-key-store.js
Introduce getCustomProviders(), saveCustomProvider(), and removeCustomProvider() with validation against builtin providers. Add getFullProviderEnvMap() to merge custom and builtin provider env mappings for unified resolution throughout the app.
IPC Communication
electron/ipc-setup.js, electron/preload-setup.js
Add three new IPC handlers (sidecar:get-custom-providers, sidecar:save-custom-provider, sidecar:remove-custom-provider) with error handling and extend the preload whitelist to allow invoking these channels.
API Key Management
src/utils/api-key-validation.js, src/utils/validators.js, src/utils/alias-resolver.js
Update validation and resolution logic to support custom providers: build dynamic endpoints for custom providers, fallback to custom provider lookup, and use the merged provider env map instead of static mappings.
Setup Flow Integration
src/sidecar/setup.js
Add runCustomProviderSetup(rl) function to interactively gather custom provider details during readline configuration and persist via config utilities.
UI & Forms
electron/setup-ui-keys.js, electron/setup-ui-keys-script.js
Add custom provider form with fields for ID, name, base URL, auth type, and env variable. Implement handlers to toggle form visibility, validate/save providers, render provider cards, and load existing custom providers on init. Update OpenRouter placeholder.
Documentation & Tests
.env.example, tests/config-fallback.test.js
Add example documentation for custom provider environment variables and update test mocks to use shared MOCK_PROVIDER_ENV_MAP with getFullProviderEnvMap() mock.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Setup UI
    participant IPC as Electron IPC
    participant Config as Config Manager
    participant Storage as File Storage
    participant Validator as API Validator

    User->>UI: Fill custom provider form<br/>(ID, name, baseURL, etc.)
    User->>UI: Click "Add Custom Provider"
    UI->>IPC: invoke('sidecar:save-custom-provider',<br/>id, provider)
    IPC->>Config: saveCustomProvider(id, provider)
    Config->>Config: Validate against BUILTIN_PROVIDERS
    Config->>Config: Normalize baseUrl & set defaults
    Config->>Storage: Write to config.json
    Storage-->>Config: Persist complete
    Config-->>IPC: Return success
    IPC-->>UI: Handler resolves with result
    UI->>UI: Update in-memory providers map
    UI->>UI: Render provider card
    UI->>UI: Reset form

    User->>UI: Select custom provider & enter API key
    User->>UI: Test connection / Save
    UI->>Validator: validateApiKey(custom provider, key)
    Validator->>Config: getCustomProviders()
    Config-->>Validator: Custom provider details
    Validator->>Validator: buildCustomEndpoint(baseURL, authType)
    Validator->>Validator: Send HTTP/HTTPS request
    Validator-->>UI: Validation result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested reviewers

  • jrenaldi79

Poem

🐰 Hop along, dear custom providers glow,
Painted forms and configs in a row.
IPC whispers, validation flows so free,
The sidecar dances with flexibility!
A rabbit's delight—more choices to sow! 🌱

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

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.

@marcveihl marcveihl closed this Mar 12, 2026
@marcveihl marcveihl deleted the test/custom-api-providers branch March 12, 2026 00:50
ellisjr added a commit to ellisjr/sidecar that referenced this pull request Mar 12, 2026
…renaldi79#2)

* fix: fall back to direct provider API when OpenRouter key is missing

When a user has GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY
set but not OPENROUTER_API_KEY, aliases like --model gemini now
automatically route through the direct provider API instead of failing
with "OPENROUTER_API_KEY required". Adds applyDirectApiFallback() which
strips the openrouter/ prefix from alias-resolved models when the
direct provider key is available. OpenRouter is still preferred when
both keys are present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: validate direct API fallback models exist on provider

When the direct API fallback triggers (no OpenRouter key), validate
that the model actually exists on the provider before proceeding.
If validation fails:
- Interactive mode: prompts user to pick from available models,
  saves choice to config.json so they're never prompted again
- Headless mode: fails with available models list and fix command

Adds model-validator.js with validateDirectModel() using the existing
model-fetcher.js infrastructure. Network errors skip validation
gracefully (don't block the user).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR feedback — opt-in validation, TTY safety, dedup

- Make --validate-model opt-in instead of always-on (feedback jrenaldi79#2)
- Add TTY guard in both bin/sidecar.js and model-validator.js (feedback jrenaldi79#3/7)
- Detect default alias when --model is omitted (feedback jrenaldi79#6)
- Replace duplicate DIRECT_API_KEYS with PROVIDER_ENV_MAP import (feedback jrenaldi79#4)
- Add deepseek to PROVIDER_ENV_MAP (feedback #1)
- Use 'openrouter/'.length instead of magic number 11 (feedback jrenaldi79#4)
- Add malformed config safety in promptModelSelection (feedback jrenaldi79#8)
- Add tests for TTY guard and malformed config behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address round 2 PR feedback — logging, saveConfig safety, deepseek

- Add logger.warn + stderr notice when direct API fallback activates (#1)
- Register --validate-model as boolean flag in cli.js, add to usage text (jrenaldi79#2)
- Add stderr notice pointing users to --validate-model on fallback (jrenaldi79#3)
- Wrap saveConfig in try/catch in promptModelSelection (jrenaldi79#4)
- Add deepseek to VALIDATION_ENDPOINTS in api-key-store.js (jrenaldi79#5)
- Add CLI tests for --validate-model flag
- Suppress stderr in config fallback tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update api-key-store test to expect 5 providers (includes deepseek)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: fix pre-existing test failures in mcp-server and api-key-store tests

- Add model param to mcp-server sidecar_start test calls (resolveModel
  now requires a model or configured default)
- Update api-key-store provider count assertion from 4 to 5 (deepseek)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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