Skip to content

chore: add new providers for pricing and new models#1126

Merged
AmanAgarwal041 merged 3 commits into
mainfrom
chore/add-provider
Apr 20, 2026
Merged

chore: add new providers for pricing and new models#1126
AmanAgarwal041 merged 3 commits into
mainfrom
chore/add-provider

Conversation

@AmanAgarwal041
Copy link
Copy Markdown
Contributor

@AmanAgarwal041 AmanAgarwal041 commented Apr 20, 2026

Important

  1. We strictly follow a issue-first approach, please first open an issue relating
    to this Pull Request.
  2. PR name follows conventional commit format: feat: ... or fix: ....

Fixes #1125

Change description:

Moves provider definitions from hardcoded TypeScript into a ClickHouse table, making providers fully dynamic — users can add, edit, and delete providers through the UI, API, or import.

New ClickHouse table

  • openlit_provider_metadata (ReplacingMergeTree) — stores provider_id, display_name, description, requires_vault,
    config_schema (JSON), is_default
  • Migration create-provider-metadata-migration.ts creates the table and seeds 14 built-in providers from DEFAULT_PROVIDERS in
    default-models.ts
  • Wired into migrations/index.ts to run alongside the existing provider/model migrations

Provider registry rewrite

  • Removed static PROVIDER_METADATA record (~160 lines) from provider-registry.ts
  • getAvailableProviders() now loads provider metadata + models in parallel from ClickHouse
  • getProviderById(), searchProviders() all query the DB
  • Uses FINAL keyword on ReplacingMergeTree queries to deduplicate
  • Static data moved to DEFAULT_PROVIDERS in default-models.ts (used only by migration seeding)

Provider CRUD API

  • POST /api/openground/providers — create a new provider
  • PUT /api/openground/providers — update provider metadata (displayName, description, requiresVault, configSchema)
  • DELETE /api/openground/providers?provider=<id> — delete provider + all its models

Provider add/edit UI

  • Add Provider button (PlusCircle icon with tooltip) in the Manage Models header
  • Edit icon (pencil) on provider headers in the sidebar — appears on hover via group/provider CSS
  • ProviderEditorDialog component — form fields: Provider ID (read-only when editing), Display Name, Description, Requires Vault toggle
  • Provider ID auto-formats on input: lowercase, spaces → hyphens, special chars stripped

Model ID auto-formatting

  • Model ID input in model-editor-panel.tsx now applies the same transformation: lowercase, spaces → hyphens, strips chars outside a-z 0-9 - / .
  • Allows path-style IDs like accounts/fireworks/models/llama-v3p1-70b-instruct

Import extended

  • POST /api/openground/models/import now accepts optional providers array
  • Existing providers are skipped by provider_id (no duplicates)
  • Response includes providersImported and providersSkipped counts
  • Import dialog placeholder updated to show the combined providers + models format

Files changed

Area Files
Table providers/table-details.ts — added OPENLIT_PROVIDER_METADATA_TABLE_NAME
Seed data providers/default-models.ts — added DEFAULT_PROVIDERS array + DefaultProviderEntry type
Migration create-provider-metadata-migration.ts (new), migrations/index.ts (wired in)
Registry providers/provider-registry.ts — rewritten, fully DB-driven
API api/openground/providers/route.ts — added POST, PUT, DELETE handlers
Import API api/openground/models/import/route.ts — extended with providers support
UI provider-editor-dialog.tsx (new), model-list-sidebar.tsx (added onEditProvider + hover pencil),
manage-models/page.tsx (Add Provider button + dialog wiring), model-editor-panel.tsx (model ID auto-formatting)
Messages en.ts — added MANAGE_PROVIDERS_* strings
Tests provider-registry.test.ts — rewritten for DB-driven architecture
Docs manage-models.mdx — added "Managing providers" section, updated import docs, added API reference table

Tests

provider-registry.test.ts fully rewritten — mocks both provider metadata and model DB queries. All 114 suites / 1716 tests pass.

Checklist

  • PR name follows conventional commit format: feat: ... or fix: ....
  • I have reviewed the contributing guidelines
  • Have you checked to ensure there aren't other open Pull Requests for the same
    update/change?
  • I have performed a self-review of this change
  • Changes have been tested
  • Changes are documented

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.

Summary by Sourcery

Make provider definitions fully dynamic by storing metadata in ClickHouse, exposing CRUD APIs and UI for managing providers, and extending import/export flows and docs accordingly.

New Features:

  • Introduce a ClickHouse-backed provider metadata table seeded with default providers and used at runtime instead of hardcoded provider definitions.
  • Add API endpoints to create, update, and delete providers, including cascading deletion of a provider’s models.
  • Add a Provider editor dialog and sidebar affordances to add and edit providers directly from the Manage Models UI.
  • Support bulk import of providers alongside models, with duplicate detection and per-type import/skip counts.

Enhancements:

  • Refactor the provider registry to load provider metadata and models from ClickHouse, making the provider list fully data-driven.
  • Auto-format provider and model IDs into normalized slugs suitable for SDK usage.
  • Extend pricing management docs with provider management workflows, updated import examples, and an API reference table.

Build:

  • Bump client package version from 1.18.0 to 1.18.1.

Documentation:

  • Document managing providers, combined provider+model imports, and the updated pricing architecture in the manage-models guide.

Tests:

  • Rewrite provider registry tests to validate the new DB-driven provider metadata and model loading behavior.

@AmanAgarwal041 AmanAgarwal041 requested a review from a team as a code owner April 20, 2026 06:40
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 20, 2026

Reviewer's Guide

Moves provider metadata from a static TypeScript map into a new ClickHouse ReplacingMergeTree table, rewires the provider registry and tests to be fully DB-driven, adds CRUD APIs and UI for managing providers, extends the import API and docs to support providers, and tightens ID auto-formatting for providers and models.

Sequence diagram for ProviderEditorDialog save flow

sequenceDiagram
  actor User
  participant ManageModelsPage
  participant ProviderEditorDialog
  participant UseFetchWrapper
  participant ProvidersRoute as ApiProvidersRoute
  participant ClickHouse

  User->>ManageModelsPage: click AddProvider or EditProvider
  ManageModelsPage->>ProviderEditorDialog: open dialog with ProviderFormData

  User->>ProviderEditorDialog: fill form and click Save
  ProviderEditorDialog->>UseFetchWrapper: fireRequest(POST or PUT, body ProviderFormData)

  UseFetchWrapper->>ApiProvidersRoute: HTTP POST or PUT /api/openground/providers
  ApiProvidersRoute->>ApiProvidersRoute: getCurrentUser()
  ApiProvidersRoute->>ApiProvidersRoute: getDBConfigByUser(true)

  alt creating provider
    ApiProvidersRoute->>ClickHouse: insert into openlit_provider_metadata
  else updating provider
    ApiProvidersRoute->>ClickHouse: ALTER TABLE openlit_provider_metadata UPDATE
  end

  ClickHouse-->>ApiProvidersRoute: success or error
  ApiProvidersRoute-->>UseFetchWrapper: JSON { success, providerId } or error

  alt success
    UseFetchWrapper-->>ProviderEditorDialog: success callback
    ProviderEditorDialog->>ManageModelsPage: onSaved()
    ManageModelsPage->>ManageModelsPage: loadProviders() and loadAllCustomModels()
  else failure
    UseFetchWrapper-->>ProviderEditorDialog: failure callback
  end
Loading

Sequence diagram for import providers and models API

sequenceDiagram
  actor User
  participant ManageModelsPage
  participant ImportRoute as ApiModelsImportRoute
  participant ClickHouse

  User->>ManageModelsPage: open Import dialog and submit JSON
  ManageModelsPage->>ImportRoute: POST /api/openground/models/import

  ImportRoute->>ImportRoute: authenticate and getDBConfigByUser(true)
  ImportRoute->>ImportRoute: parse body.providers and body.models

  alt providers present
    ImportRoute->>ClickHouse: SELECT provider_id FROM openlit_provider_metadata FINAL
    ClickHouse-->>ImportRoute: existing provider_ids
    ImportRoute->>ImportRoute: build providersToInsert
    alt providersToInsert not empty
      ImportRoute->>ClickHouse: INSERT INTO openlit_provider_metadata values providersToInsert
      ClickHouse-->>ImportRoute: ok
    end
  end

  alt models present
    ImportRoute->>ClickHouse: SELECT provider, model_id FROM openlit_provider_models
    ClickHouse-->>ImportRoute: existing provider model pairs
    ImportRoute->>ImportRoute: build modelsToInsert
    alt modelsToInsert not empty
      ImportRoute->>ClickHouse: INSERT INTO openlit_provider_models values modelsToInsert
      ClickHouse-->>ImportRoute: ok
    end
  end

  ImportRoute-->>ManageModelsPage: JSON { imported, skipped, providersImported, providersSkipped }
  ManageModelsPage-->>User: show import result
Loading

ER diagram for provider metadata and models tables

erDiagram
  openlit_provider_metadata {
    String provider_id PK
    String display_name
    String description
    Boolean requires_vault
    String config_schema
    Boolean is_default
    DateTime created_at
    DateTime updated_at
  }

  openlit_provider_models {
    String provider
    String model_id
    String displayName
    Float inputPricePerMToken
    Float outputPricePerMToken
    String modelType
    String capabilities
  }

  openlit_providers {
    String provider
    String api_key
    String config
  }

  openlit_provider_metadata ||--o{ openlit_provider_models : has_models
  openlit_provider_metadata ||--o{ openlit_providers : has_api_configs
Loading

Class diagram for ProviderRegistry and default provider seed data

classDiagram
  class ProviderMetadata {
    string providerId
    string displayName
    string description
    boolean requiresVault
    Record configSchema
    ModelMetadata[] supportedModels
  }

  class ModelMetadata {
    string provider
    string model_id
    string displayName
    float inputPricePerMToken
    float outputPricePerMToken
    string modelType
    string[] capabilities
  }

  class ProviderMetadataRow {
    string provider_id
    string display_name
    string description
    boolean requires_vault
    string config_schema
    boolean is_default
  }

  class ProviderRegistry {
    +getAvailableProviders(databaseConfigId string) Promise~ProviderMetadata[]~
    +getProviderById(providerId string, databaseConfigId string) Promise~ProviderMetadata~
    +searchProviders(query string, databaseConfigId string) Promise~ProviderMetadata[]~
    +getModelsForProvider(providerId string, databaseConfigId string) Promise~ModelMetadata[]~
  }

  class DefaultProviderEntry {
    string providerId
    string displayName
    string description
    boolean requiresVault
    Record configSchema
  }

  class DefaultModelEntry {
    string provider
    string model_id
    string displayName
    float inputPricePerMToken
    float outputPricePerMToken
    string modelType
    string[] capabilities
  }

  class DEFAULT_PROVIDERS {
    <<array>>
  }

  class DEFAULT_MODELS_BY_PROVIDER {
    <<record>>
  }

  ProviderRegistry ..> ProviderMetadataRow : uses
  ProviderRegistry ..> ProviderMetadata : returns
  ProviderRegistry ..> ModelMetadata : returns
  ProviderMetadataRow ..> ProviderMetadata : parsed_into
  DEFAULT_PROVIDERS ..> DefaultProviderEntry : elements
  DEFAULT_MODELS_BY_PROVIDER ..> DefaultModelEntry : elements

  class CreateProviderMetadataMigration {
    +CreateProviderMetadataMigration(databaseConfigId string) Promise~object~
  }

  class migrationHelper {
    +migrationHelper(config object) Promise~object~
  }

  class dataCollector {
    +dataCollector(params object, mode string, databaseConfigId string) Promise~object~
  }

  CreateProviderMetadataMigration ..> DEFAULT_PROVIDERS : seeds_from
  CreateProviderMetadataMigration ..> dataCollector : executes_queries
  CreateProviderMetadataMigration ..> migrationHelper : uses
Loading

Class diagram for provider editor UI components

classDiagram
  class ProviderFormData {
    string providerId
    string displayName
    string description
    boolean requiresVault
  }

  class ProviderEditorDialogProps {
    boolean open
    function onOpenChange
    ProviderFormData provider
    function onSaved
  }

  class ProviderEditorDialog {
    +ProviderEditorDialog(props ProviderEditorDialogProps)
    -ProviderFormData formData
    -boolean isEditing
    -handleSave() void
  }

  class ModelListSidebarProps {
    ProviderMetadata[] providers
    ModelMetadata[] models
    string selectedProviderId
    string selectedModelId
    boolean selectedIsCustom
    function onSelectModel
    function onAddNew
    function onEditProvider
  }

  class ModelListSidebar {
    +ModelListSidebar(props ModelListSidebarProps)
  }

  class ManageModelsPageState {
    string selectedProviderId
    string selectedModelId
    boolean isCustomModel
    boolean isAddingNew
    boolean showImport
    boolean showSdkUsage
    boolean showProviderEditor
    ProviderFormData editingProvider
  }

  class ManageModelsPage {
    +ManageModelsPage()
    -handleAddProvider() void
    -handleEditProvider(provider ProviderMetadata) void
    -handleProviderSaved() void
  }

  ProviderEditorDialogProps o--> ProviderFormData
  ProviderEditorDialog ..> ProviderFormData : manages
  ManageModelsPage ..> ProviderEditorDialog : renders
  ManageModelsPage ..> ModelListSidebar : renders
  ModelListSidebarProps ..> ProviderMetadata : uses
  ModelListSidebarProps ..> ModelMetadata : uses
  ModelListSidebar ..> ModelListSidebarProps : props
  ManageModelsPage ..> ManageModelsPageState : uses_state
Loading

File-Level Changes

Change Details Files
Provider metadata moved from hardcoded TypeScript to a new ClickHouse ReplacingMergeTree table and wired into migrations.
  • Introduce OPENLIT_PROVIDER_METADATA_TABLE_NAME constant for the new table.
  • Define DEFAULT_PROVIDERS and DefaultProviderEntry in default-models.ts as the seed source for built-in providers.
  • Add create-provider-metadata-migration.ts to create the provider metadata table and seed 14 default providers, and register it in the migrations index to run alongside existing provider/model migrations.
src/client/src/lib/platform/providers/table-details.ts
src/client/src/lib/platform/providers/default-models.ts
src/client/src/clickhouse/migrations/create-provider-metadata-migration.ts
src/client/src/clickhouse/migrations/index.ts
Provider registry rewritten to load providers and models dynamically from ClickHouse instead of static metadata.
  • Remove the large static PROVIDER_METADATA record and associated metadata helpers.
  • Add helper functions to load all providers or a specific provider from the provider metadata table using dataCollector and Sanitizer, including JSON parsing of config_schema and FINAL queries for ReplacingMergeTree.
  • Update getAvailableProviders, getProviderById, searchProviders, and getProviderModels to query ClickHouse and merge providers with their models, handling DB errors gracefully.
src/client/src/lib/platform/providers/provider-registry.ts
Add provider CRUD API endpoints to create, update, and delete providers and cascade deletes to their models.
  • Implement POST /api/openground/providers to insert a new provider metadata row after validating required fields and composing the insert payload.
  • Implement PUT /api/openground/providers to update provider fields via an ALTER TABLE UPDATE statement built from the provided body fields, using Sanitizer for string values.
  • Implement DELETE /api/openground/providers to delete a provider from the metadata table and all its models from openlit_provider_models in parallel, with validation and error handling.
src/client/src/app/api/openground/providers/route.ts
Extend the models import API to optionally import providers alongside models and report granular counts.
  • Read an optional providers array from the request body and compute existing provider IDs from the provider metadata table to avoid duplicates.
  • Insert only new providers into the provider metadata table, tracking providersImported and providersSkipped.
  • Retain model import behavior while separating model duplicate detection and insertion, returning imported/skipped counts for both providers and models and updating error messages and examples accordingly.
src/client/src/app/api/openground/models/import/route.ts
src/client/src/app/(playground)/manage-models/page.tsx
docs/latest/openlit/pricing/manage-models.mdx
Add UI for creating and editing providers from the Manage Models page, including ID auto-formatting and messaging.
  • Introduce ProviderEditorDialog component to handle add/edit provider flows, including form state, POST/PUT calls, validation, and success/error toasts, with providerId auto-formatted and locked on edit.
  • Add an Add Provider button with tooltip to the Manage Models header and wire up dialog open/close and refresh callbacks for providers and models.
  • Update the model list sidebar to accept an optional onEditProvider callback and show a hover-only pencil icon for editing provider metadata next to the existing add-model button.
  • Add provider-management copy and labels to the messages file for reuse across the UI.
src/client/src/components/(playground)/openground/provider-editor-dialog.tsx
src/client/src/app/(playground)/manage-models/page.tsx
src/client/src/components/(playground)/openground/model-list-sidebar.tsx
src/client/src/constants/messages/en.ts
Tighten ID auto-formatting for model IDs to match provider ID slug behavior and allow path-style IDs.
  • Update the model editor panel’s model_id input onChange handler to normalize to lowercase, replace spaces with hyphens, and restrict characters to a-z, 0-9, hyphen, slash, and dot.
  • Ensure this behavior only applies while adding new models (disabled when editing existing models).
src/client/src/components/(playground)/openground/model-editor-panel.tsx
Align tests, documentation, and package metadata with the new DB-driven provider architecture.
  • Rewrite provider-registry tests to mock ClickHouse queries for provider metadata and models, covering success, empty, and error paths, plus search behavior and model retrieval.
  • Expand docs for Manage Models to explain provider management, import format with providers + models, and add an API reference table reflecting new endpoints and the provider metadata table.
  • Bump the client package version to 1.18.1 to reflect the new capabilities.
src/client/src/__tests__/lib/platform/providers/provider-registry.test.ts
docs/latest/openlit/pricing/manage-models.mdx
src/client/package.json
src/client/package-lock.json

Assessment against linked issues

Issue Objective Addressed Explanation
#1125 Introduce a ClickHouse-backed provider metadata store (openlit_provider_metadata) and migrate provider registration to load provider definitions (including seeded built-ins) from the database instead of hardcoded TypeScript.
#1125 Provide full dynamic provider management (add, edit, delete) via API and UI, including provider ID auto-formatting and model ID auto-formatting in the model editor.
#1125 Extend the import workflow and documentation so that import/export supports providers alongside models, and document provider CRUD and the new API endpoints.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 20, 2026

✅ Jest Coverage — Great (92.08%)

Metric Coverage
Statements ✅ 93.48%
Branches ✅ 92.08%
Functions ✅ 94.84%
Lines ✅ 93.48%

Great: >90%  |  ⚠️ Good: 80–90%  |  ❌ Poor: <80%

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 3 issues, and left some high level feedback:

  • In the models import API, you handle errors from the models insert but ignore the result of the providers insert (dataCollector return value); consider checking err there as well so provider import failures are surfaced instead of silently continuing.
  • In the providers DELETE handler you hardcode openlit_provider_models rather than using OPENLIT_PROVIDER_MODELS_TABLE_NAME; aligning this with the constant used elsewhere will reduce duplication and make future table name changes safer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the models import API, you handle errors from the models insert but ignore the result of the providers insert (`dataCollector` return value); consider checking `err` there as well so provider import failures are surfaced instead of silently continuing.
- In the providers DELETE handler you hardcode `openlit_provider_models` rather than using `OPENLIT_PROVIDER_MODELS_TABLE_NAME`; aligning this with the constant used elsewhere will reduce duplication and make future table name changes safer.

## Individual Comments

### Comment 1
<location path="src/client/src/app/api/openground/providers/route.ts" line_range="222-231" />
<code_context>
+			);
+		}
+
+		const updateFields: string[] = [];
+		if (displayName !== undefined) {
+			updateFields.push(`display_name = '${Sanitizer.sanitizeValue(displayName)}'`);
+		}
+		if (description !== undefined) {
+			updateFields.push(`description = '${Sanitizer.sanitizeValue(description)}'`);
+		}
+		if (requiresVault !== undefined) {
+			updateFields.push(`requires_vault = ${!!requiresVault}`);
+		}
+		if (configSchema !== undefined) {
+			updateFields.push(`config_schema = '${Sanitizer.sanitizeValue(JSON.stringify(configSchema))}'`);
+		}
+		updateFields.push(`updated_at = now()`);
+
+		const query = `
+			ALTER TABLE ${OPENLIT_PROVIDER_METADATA_TABLE_NAME}
+			UPDATE ${updateFields.join(", ")}
</code_context>
<issue_to_address>
**🚨 issue (security):** Building the UPDATE statement via string interpolation is fragile and could allow SQL injection if Sanitizer is bypassed.

Here we interpolate user-controlled values (displayName, description, configSchema) directly into SQL. Even with `Sanitizer.sanitizeValue`, this is fragile: any missed field or future change could reopen SQL injection or quoting bugs. Prefer a parameterized/structured UPDATE via the existing `dataCollector` APIs if possible, or at least a single shared helper that returns safely quoted ClickHouse literals instead of manual string concatenation.
</issue_to_address>

### Comment 2
<location path="src/client/src/app/api/openground/providers/route.ts" line_range="297-298" />
<code_context>
+		const sanitizedId = Sanitizer.sanitizeValue(providerId);
+
+		// Delete provider metadata + all its models
+		const [metaResult, modelsResult] = await Promise.all([
+			dataCollector(
+				{
+					query: `DELETE FROM ${OPENLIT_PROVIDER_METADATA_TABLE_NAME} WHERE provider_id = '${sanitizedId}'`,
</code_context>
<issue_to_address>
**suggestion:** Use the shared table constant instead of hardcoding `openlit_provider_models` in the DELETE query.

This DELETE is the only provider-related query that hardcodes `openlit_provider_models` instead of using the constants from `table-details.ts`. Please switch it to `OPENLIT_PROVIDER_MODELS_TABLE_NAME` to stay consistent and avoid issues if the table name changes later.
</issue_to_address>

### Comment 3
<location path="src/client/src/lib/platform/providers/provider-registry.ts" line_range="40-49" />
<code_context>
+async function loadAllProvidersFromDb(
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Swallowing DB errors and returning an empty provider list can hide operational issues.

If ClickHouse is down or the query fails, this function logs the error but still returns an empty array. Callers like `getAvailableProviders` will treat that as “no providers configured” instead of a backend failure. Please either propagate the error or distinguish between “no rows” and “query failed” so the API can respond with an appropriate 5xx instead of a successful empty result.

Suggested implementation:

```typescript
/**
 * Load all provider metadata rows from ClickHouse.
 *
 * Errors from ClickHouse are intentionally allowed to propagate so that callers
 * can distinguish between “no providers configured” and backend failures.
 */
async function loadAllProvidersFromDb(
	databaseConfigId: string
): Promise<Omit<ProviderMetadata, "supportedModels">[]> {
	const query = `
			SELECT
				provider_id,
				display_name,
				description,
				requires_vault,
				config_schema,

```

The current implementation likely has a `catch` block later in `loadAllProvidersFromDb` that logs the error and returns `[]`. That `catch` block (including any `console.error`/`logger.error` and `return []`) should be removed so that any ClickHouse/query errors bubble up to the caller.

Callers like `getAvailableProviders` that currently assume `loadAllProvidersFromDb` never throws will need to be updated to either:
1. Let the error propagate all the way to the HTTP layer (so it becomes a 5xx), or
2. Wrap `loadAllProvidersFromDb` in a `try/catch` and convert the failure into an appropriate error response, rather than treating it as an empty provider list.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/client/src/app/api/openground/providers/route.ts Outdated
Comment thread src/client/src/app/api/openground/providers/route.ts
Comment thread src/client/src/lib/platform/providers/provider-registry.ts Outdated
Comment thread src/client/src/lib/platform/providers/provider-registry.ts Fixed
@AmanAgarwal041 AmanAgarwal041 merged commit b9a947b into main Apr 20, 2026
9 checks passed
@AmanAgarwal041 AmanAgarwal041 deleted the chore/add-provider branch April 20, 2026 10:23
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.

Feature: Dynamic Provider Management — Add, Edit, and Import Providers

2 participants