DocumentsLobeHub
AI Provider Configuration
AI Provider Configuration
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

AI Provider Configuration#

AI Provider Configuration covers how users connect LobeHub to AI backends (API keys, base URLs, authentication type, model fetching options). The feature spans a Zustand store slice that manages server-fetched provider data and a React form component that lets users edit credentials and toggle behavioral flags.

Key entry points:

LayerPath
Store slice (actions)src/store/aiInfra/slices/aiProvider/action.ts
Store slice (initial state)src/store/aiInfra/slices/aiProvider/initialState.ts
Store slice (selectors)src/store/aiInfra/slices/aiProvider/selectors.ts
Config UI componentsrc/routes/(main)/settings/provider/features/ProviderConfig/index.tsx
Controlled inputssrc/components/FormInput/FormPassword.tsx , src/components/FormInput/FormInput.tsx

Store Architecture#

State Shape#

The aiProvider slice holds two parallel caches for each provider :

  • aiProviderDetailMapRecord<string, AiProviderDetailItem>: provider metadata, keyVaults, and settings. Populated by useFetchAiProviderItem.
  • aiProviderRuntimeConfigRecord<string, AiProviderRuntimeConfig>: credential values and runtime flags used by selectors at inference time. Populated by useFetchAiProviderRuntimeState.

Loading and mutation state are tracked as ID arrays rather than per-key booleans:

  • aiProviderLoadingIds — providers currently being fetched or toggled
  • aiProviderConfigUpdatingIds — providers whose config is being saved

Selectors in aiProviderSelectors derive booleans from these arrays (e.g., isAiProviderConfigLoading, isProviderConfigUpdating).

SWR Data Fetching#

Three SWR keys are used :

  • FETCH_AI_PROVIDER — list of all providers
  • FETCH_AI_PROVIDER_ITEM — detail for a single provider (keyed by provider ID)
  • FETCH_AI_PROVIDER_RUNTIME_STATE — enabled providers, models, and per-provider runtime config (keyed by login status)

refreshAiProviderRuntimeState invalidates both the logged-in and logged-out variants simultaneously .

Optimistic Updates in updateAiProviderConfig#

When a config field changes, updateAiProviderConfig follows this sequence:

  1. Adds the provider ID to aiProviderConfigUpdatingIds (loading indicator).
  2. Calls aiProviderService.updateAiProviderConfig (network request).
  3. Immediately patches both aiProviderDetailMap and aiProviderRuntimeConfig in local state for instant UI feedback — no waiting for SWR revalidation .
  4. Calls refreshAiProviderDetail to revalidate SWR caches.
  5. Removes the provider ID from aiProviderConfigUpdatingIds.

Runtime State Readiness Guard#

ensureAiProviderRuntimeStateReady races the runtime state fetch against a 3-second timeout. This is a no-op when already initialized, making it safe to call from anywhere before reading model capability data.

ProviderConfig Component#

ProviderConfig is the single form component rendered for every provider in the settings panel. It is memo-wrapped and driven entirely by the Zustand store.

Store Subscription#

The component subscribes to six store values in a single useAiInfraStore selector call :

SelectorUsed for
providerDetailById(id)Form initial data
updateAiProviderConfigSave action
isProviderEnabled(id)Visual state (greyscale header)
isAiProviderConfigLoading(id)Show skeletons
isProviderConfigUpdating(id)Show inline spinner on fields
providerConfigById(id)Runtime credentials (preferred over detail map)

Form Initialization Lifecycle#

Form values are set via useLayoutEffect with a lastInitializedIdRef guard . The form only reinitializes when:

  • The component first mounts (lastInitializedIdRef.current === null), or
  • The provider ID changes (user navigates to a different provider).

This prevents the form from resetting mid-edit during background SWR refreshes. Data from providerRuntimeConfig is merged on top of data to ensure nested config fields like enableResponseApi are correctly seeded .

Debounced onChange and Connection-Test Guard#

Every form change calls debouncedHandleValueChange with a 500 ms debounce. A isCheckingConnection ref blocks dispatch while a connection test is in progress :

  • Before test: the ref is set to true; the latest form values are force-saved.
  • After test: the ref is reset to false; normal debounced saves resume.

Conditional Field Visibility#

AntdForm.useWatch tracks six credential fields (baseURL, endpoint, apiKey, accessKeyId, secretAccessKey, username, password) in real time. The Client Fetch and Responses API switches are only rendered when the relevant fields are populated . This avoids showing advanced options before a user has entered credentials.

OAuth vs. Standard Providers#

When settings.authType === 'oauthDeviceFlow', the form is replaced by the OAuthDeviceFlowAuth component and only shown again once the OAuth status query returns ACTIVE .

Permission Gating#

usePermission('manage_provider_key') gates the form's disabled prop . Non-permitted users can view but not edit provider credentials.

Controlled Input Components#

FormPassword and FormInput are thin wrappers over @lobehub/ui inputs that implement a buffer-then-flush pattern:

  • Internal state holds the in-progress value without triggering onChange on every keystroke.
  • onChange fires only on blur or Enter key press, reducing the number of debounced config saves.
  • Both components use a useIMECompositionEvent hook to suppress onChange during IME composition (CJK input), preventing partial character sequences from being saved as credentials.
  • FormPassword sets autoComplete="new-password" to prevent browser autofill from overwriting API keys with saved login passwords .

These are the only input components used inside the API key and base URL form items in ProviderConfig.

Key Types and Service Layer#

SymbolLocationNotes
AiProviderDetailItem@/types/aiProviderFull provider record including keyVaults, settings, checkModel, logo
UpdateAiProviderConfigParams@/types/aiProviderPayload for config saves; includes fetchOnClient, config.enableResponseApi, and keyVaults fields
AiProviderRuntimeConfig@/types/aiProviderPer-provider runtime shape stored in aiProviderRuntimeConfig
aiProviderSelectors@/store/aiInfraAll provider selectors; includes providerDetailById, providerConfigById, isProviderEnabled, isAiProviderConfigLoading, isProviderConfigUpdating
aiProviderService@/services/aiProviderService layer for CRUD operations; called directly from action methods

The ProviderConfigProps interface allows per-provider customization: apiKeyItems (override default API key fields), apiKeyUrl (link to provider's key console), normalizeConfigValues (transform form values before saving), and checkErrorRender (custom connection-test error UI).