Skip to content

feat: Add full provider variable metadata and multi-variable support#11446

Merged
HimavarshaVS merged 134 commits intomainfrom
EJ/add-multi-api-support
Feb 27, 2026
Merged

feat: Add full provider variable metadata and multi-variable support#11446
HimavarshaVS merged 134 commits intomainfrom
EJ/add-multi-api-support

Conversation

@edwinjosechittilappilly
Copy link
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly commented Jan 26, 2026

Enhances provider variable handling by introducing a metadata structure for all required variables per provider, including support for providers with multiple required variables (e.g., IBM WatsonX). Updates backend API to return full variable info, adapts frontend to dynamically render and save multiple variables, and adds comprehensive tests for the new API response. Also updates static mappings and introduces a new React hook for fetching provider variable metadata.

Summary by CodeRabbit

  • New Features

    • Provider configuration now supports multiple variables per provider instead of just API keys, enabling complex multi-field setups like IBM WatsonX (API key, Project ID, URL)
    • Enhanced provider metadata endpoint returns detailed variable information including descriptions, required flags, and secret indicators
    • Updated configuration interface dynamically renders appropriate input types per variable
  • Tests

    • Added comprehensive test coverage for provider variable mapping and backward compatibility
  • Documentation

    • Added deprecation notice directing to the new provider metadata API endpoint

Enhances provider variable handling by introducing a metadata structure for all required variables per provider, including support for providers with multiple required variables (e.g., IBM WatsonX). Updates backend API to return full variable info, adapts frontend to dynamically render and save multiple variables, and adds comprehensive tests for the new API response. Also updates static mappings and introduces a new React hook for fetching provider variable metadata.
Copilot AI review requested due to automatic review settings January 26, 2026 16:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 26, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The changes extend provider variable configuration from a single API key per provider to support multiple variables with metadata. The backend API endpoint returns enriched variable information including required, secret, and option fields. Frontend, service, and core model logic are updated to handle multi-variable validation, storage, and UI rendering, with new utility functions for variable lookup and IBM WatsonX multi-variable support.

Changes

Cohort / File(s) Summary
Backend API Endpoint
src/backend/base/langflow/api/v1/models.py
Updated /provider-variable-mapping endpoint to return full variable metadata objects per provider instead of simple string mappings; changed return type from dict[str, str] to dict[str, list[dict]] and added import for get_model_provider_metadata.
Backend Service Logic
src/backend/base/langflow/services/variable/service.py
Enhanced variable service to build comprehensive provider-to-variable mappings using full metadata; introduced secret vs non-secret variable handling; replaced per-key API key logic with metadata-driven validation and default field configuration.
Backend Tests
src/backend/tests/unit/api/v1/test_models_enabled_providers.py
Added three test cases validating provider-variable-mapping endpoint behavior, multi-variable providers (IBM WatsonX), and backward compatibility of primary variable mapping.
Frontend Type Definitions
src/frontend/src/constants/providerConstants.ts
Added new ProviderVariable interface with fields for variable metadata (name, key, description, required, is_secret, is_list, options); marked existing PROVIDER_VARIABLE_MAPPING as deprecated.
Frontend API Hook
src/frontend/src/controllers/API/queries/models/use-get-provider-variables.ts
Introduced new useGetProviderVariables hook to fetch provider variables from API with caching and error handling; defined ProviderVariablesMapping type.
Frontend UI Component
src/frontend/src/modals/modelProviderModal/components/ModelProvidersContent.tsx
Refactored to support multi-variable configuration with batch save workflow; added masked value display for secrets; replaced single API key input with dynamic variable inputs per provider; updated validation and success feedback logic.
LFX Package Exports
src/lfx/src/lfx/base/models/__init__.py
Re-exported four new utility functions from unified_models in public API: get_model_provider_metadata, get_provider_all_variables, get_provider_from_variable_key, get_provider_required_variable_keys.
LFX Core Model Logic
src/lfx/src/lfx/base/models/unified_models.py
Restructured provider metadata from single variable_name to variables array with detailed metadata per variable; added utility functions for variable lookup and required variable filtering; updated validation logic to check all required variables per provider; enhanced IBM WatsonX to support API key, project ID, and URL.
LFX Environment Constants
src/lfx/src/lfx/services/settings/constants.py
Added three IBM WatsonX environment variables (WATSONX_APIKEY, WATSONX_PROJECT_ID, WATSONX_URL) to VARIABLES_TO_GET_FROM_ENVIRONMENT list.

Sequence Diagram(s)

sequenceDiagram
    participant FrontendUI as Frontend UI
    participant APIHook as API Hook
    participant BackendAPI as Backend API
    participant Service as Variable Service
    participant LFXCore as LFX Core
    participant Storage as Variable Storage

    FrontendUI->>APIHook: useGetProviderVariables()
    APIHook->>BackendAPI: GET /api/v1/models/provider-variable-mapping
    BackendAPI->>LFXCore: get_model_provider_metadata()
    LFXCore-->>BackendAPI: {provider: [{variable_key, required, is_secret, options, ...}]}
    BackendAPI-->>APIHook: Provider variables mapping
    APIHook-->>FrontendUI: Update state with variable metadata

    FrontendUI->>FrontendUI: Render dynamic inputs for each variable
    Note over FrontendUI: Display required/secret flags,<br/>dropdowns for options, text inputs

    FrontendUI->>FrontendUI: User enters/selects values for all variables
    FrontendUI->>BackendAPI: POST/PATCH save all variables (batch)
    BackendAPI->>Service: Process variable updates
    Service->>LFXCore: get_provider_required_variable_keys(provider)
    LFXCore-->>Service: Required variable keys for provider
    Service->>Storage: Validate & store all required variables
    Storage-->>Service: Success/error per variable
    Service->>LFXCore: _validate_and_get_enabled_providers()
    LFXCore-->>Service: Enabled providers (all required vars present)
    Service-->>BackendAPI: Success/aggregated errors
    BackendAPI-->>FrontendUI: Update status & clear inputs
    FrontendUI->>FrontendUI: Mark provider as enabled, refresh queries
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR adds backend tests for the new provider-variable-mapping endpoint but omits frontend test coverage for the new useGetProviderVariables hook and ModelProvidersContent component refactoring despite significant new functionality. Add unit tests for useGetProviderVariables hook and ModelProvidersContent component; fix unused fixtures in test_backward_compatible_variable_mapping; update hook error handling to rethrow instead of returning empty objects.
Test Quality And Coverage ⚠️ Warning Test coverage is significantly incomplete with no frontend tests for 560-line component changes, zero tests for new hook, and limited backend smoke tests only. Add comprehensive tests for backend error scenarios, frontend hook including error cases, component multi-variable rendering, batch save, secret masking, and service layer logic.
Test File Naming And Structure ⚠️ Warning Test file has unused fixtures (ARG001 violation), no frontend test file for use-get-provider-variables.ts, and backend tests lack error/edge case coverage. Remove unused fixtures from test_backward_compatible_variable_mapping, create frontend test file with error scenarios, add backend error condition tests.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly matches the main objective of adding full provider variable metadata and multi-variable support across the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 80.00%.
Excessive Mock Usage Warning ✅ Passed The test file demonstrates appropriate and minimal mock usage targeting only external dependencies, with new provider-variable-mapping tests using zero mocks for real API behavior validation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch EJ/add-multi-api-support

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.

@github-actions github-actions bot added the enhancement New feature or request label Jan 26, 2026
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jan 26, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 26, 2026

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 19%
18.76% (6154/32799) 12.44% (3187/25604) 12.54% (878/6999)

Unit Test Results

Tests Skipped Failures Errors Time
2326 0 💤 0 ❌ 0 🔥 31.476s ⏱️

@codecov
Copy link

codecov bot commented Jan 26, 2026

Codecov Report

❌ Patch coverage is 19.48529% with 876 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.32%. Comparing base (c1b4238) to head (64ef441).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...delProviderModal/hooks/useProviderConfiguration.ts 0.00% 245 Missing ⚠️
src/lfx/src/lfx/base/models/unified_models.py 10.94% 236 Missing ⚠️
...iderModal/components/ProviderConfigurationForm.tsx 0.00% 111 Missing ⚠️
src/lfx/src/lfx/base/models/model_utils.py 21.48% 94 Missing and 1 partial ⚠️
src/backend/base/langflow/api/v1/models.py 39.70% 41 Missing ⚠️
...delInputComponent/hooks/useModelConnectionLogic.ts 0.00% 41 Missing ⚠️
...ProviderModal/components/ModelProvidersContent.tsx 0.00% 32 Missing ⚠️
...s/API/queries/models/use-get-provider-variables.ts 0.00% 14 Missing ⚠️
src/backend/base/langflow/api/v1/variable.py 16.66% 10 Missing ⚠️
src/backend/base/langflow/agentic/api/router.py 11.11% 8 Missing ⚠️
... and 11 more

❌ Your patch status has failed because the patch coverage (19.48%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (42.03%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #11446      +/-   ##
==========================================
- Coverage   35.54%   35.32%   -0.22%     
==========================================
  Files        1529     1534       +5     
  Lines       74372    75081     +709     
  Branches    11154    11312     +158     
==========================================
+ Hits        26433    26521      +88     
- Misses      46502    47113     +611     
- Partials     1437     1447      +10     
Flag Coverage Δ
backend 55.25% <52.38%> (-0.02%) ⬇️
frontend 16.98% <13.22%> (-0.20%) ⬇️
lfx 42.03% <17.80%> (-0.38%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...base/langflow/agentic/services/provider_service.py 97.72% <100.00%> (+27.95%) ⬆️
...backend/base/langflow/services/variable/service.py 87.80% <100.00%> (+1.94%) ⬆️
src/frontend/src/constants/providerConstants.ts 100.00% <100.00%> (ø)
...lers/API/queries/models/use-get-model-providers.ts 84.61% <ø> (ø)
...I/queries/variables/use-delete-global-variables.ts 38.46% <ø> (+0.96%) ⬆️
...modelProviderModal/components/ProviderListItem.tsx 96.00% <100.00%> (+0.16%) ⬆️
src/lfx/src/lfx/services/settings/constants.py 100.00% <ø> (ø)
...base/langflow/agentic/services/flow_preparation.py 96.00% <80.00%> (+0.34%) ⬆️
...c/frontend/src/modals/modelProviderModal/index.tsx 0.00% <0.00%> (ø)
...als/modelProviderModal/components/ProviderList.tsx 80.76% <60.00%> (-0.72%) ⬇️
... and 18 more

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jan 26, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds structured provider variable metadata (supporting multiple required variables per provider) and updates backend + frontend to use the richer mapping, including tests for the new API response.

Changes:

  • Backend: replaces single variable_name mapping with per-provider variables[] metadata and exposes it via /provider-variable-mapping.
  • Frontend: introduces a new query hook and updates the provider modal to render/save multiple variables dynamically.
  • Tests: adds unit coverage to validate the new endpoint response and backward-compatible mapping behavior.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/lfx/src/lfx/services/settings/constants.py Adds IBM WatsonX env vars to the global “variables to load” list.
src/lfx/src/lfx/base/models/unified_models.py Introduces multi-variable provider metadata and updates provider enablement/validation logic.
src/lfx/src/lfx/base/models/init.py Re-exports new provider-variable helper functions.
src/backend/base/langflow/api/v1/models.py Updates provider-variable-mapping endpoint to return full variable metadata.
src/backend/base/langflow/services/variable/service.py Uses provider metadata to set default_fields for all provider variables and validates secrets.
src/frontend/src/constants/providerConstants.ts Adds ProviderVariable interface and deprecates static mapping usage.
src/frontend/src/controllers/API/queries/models/use-get-provider-variables.ts Adds hook to fetch provider variable metadata from the API.
src/frontend/src/modals/modelProviderModal/components/ModelProvidersContent.tsx Updates UI to render/save multiple variables, including dropdown options.
src/backend/tests/unit/api/v1/test_models_enabled_providers.py Adds tests for the new endpoint response and IBM WatsonX multi-variable behavior.
Files not reviewed (1)
  • src/frontend/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +394 to +396
for provider in provider_variable_map:
# Get all required variable keys for this provider
required_var_keys = get_provider_required_variable_keys(provider)
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

_validate_and_get_enabled_providersdecrypts every required variable value. With the new metadata, some required variables are explicitly non-secret (e.g.,WATSONX_PROJECT_ID, WATSONX_URL) and will likely be stored unencrypted; attempting to decrypt those will fail and prevent the provider from ever being enabled. Fix by looking up each required variable’s metadata and only decrypting values for is_secret=True; for non-secret variables, validate presence using the raw stored value instead of decrypt_api_key` (and ensure the function is passed the right variable set if it currently only includes credentials).

Copilot uses AI. Check for mistakes.
Comment on lines 441 to 442

return enabled
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

This will mark any provider with zero “required” variables as enabled unconditionally. For Ollama (where the base URL is optional in metadata), this is a behavior change vs. the previous logic (which only enabled providers when a corresponding variable existed). Consider requiring that some provider variable exists (e.g., the “primary” variable from provider_variable_map[provider] or any variable in storage) before adding it to enabled, rather than enabling by default.

Suggested change
return enabled
# Provider has no required variables (like Ollama with optional base URL).
# Only enable the provider if at least one configured variable exists
# (for example, the "primary" variable from provider_variable_map).
primary_var_name = provider_variable_map.get(provider)
if primary_var_name and primary_var_name in credential_variables:
enabled.add(provider)

Copilot uses AI. Check for mistakes.
Comment on lines +120 to +127
if (selectedProvider && isUserInputRef.current) {
// Find the variable that was just changed and has a value
const variableToSave = providerVariables.find((v) =>
variableValues[v.variable_key]?.trim(),
);
if (variableToSave) {
handleSaveVariable(variableToSave);
}
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The debounced autosave picks the first variable in providerVariables that currently has a non-empty value, not the variable that was last edited. For providers with multiple fields (e.g., WatsonX), once the first field is filled, subsequent edits to other fields will keep re-saving the first field and may never persist the others. Track the “last changed variable_key” (e.g., via a ref/state set in each onChange/onValueChange handler) and save that specific variable instead of using find(...).

Copilot uses AI. Check for mistakes.

const onError = (error: any) => {
setValidationFailed(true);
setSavingVariableKey(null);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

On error you clear savingVariableKey, but the UI’s error indicator is gated on savingVariableKey === variable.variable_key. This makes it impossible to render the error icon for the field that failed. Use a separate piece of state for “failedVariableKey” (or keep savingVariableKey until the UI can display and the user edits again) so the error is attributable to the correct input.

Suggested change
setSavingVariableKey(null);

Copilot uses AI. Check for mistakes.
Comment on lines +456 to +465
endIcon={
isSaving
? "LoaderCircle"
: validationFailed &&
savingVariableKey === variable.variable_key
? "X"
: isConfigured
? "Check"
: undefined
}
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

Because savingVariableKey is set to null in onError, the condition validationFailed && savingVariableKey === variable.variable_key will never be true after a failed save, so the “X” icon won’t show. Tie the error state to the failing variable via a dedicated failedVariableKey, or don’t null out the key until after the error is rendered/acknowledged.

Copilot uses AI. Check for mistakes.
Comment on lines +190 to 205
async def get_model_provider_mapping() -> dict[str, list[dict]]:
"""Return provider variables mapping with full variable info.

Each provider maps to a list of variable objects containing:
- variable_name: Display name shown to user
- variable_key: Environment variable key
- description: Help text for the variable
- required: Whether the variable is required
- is_secret: Whether to treat as credential
- is_list: Whether it accepts multiple values
- options: Predefined options for dropdowns
"""
metadata = get_model_provider_metadata()
return {provider: meta.get("variables", []) for provider, meta in metadata.items()}


Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

This endpoint changes its response shape from dict[str, str] (provider → variable key) to dict[str, list[dict]] (provider → variable metadata list). Since the path stayed the same, existing clients expecting the prior schema will break. If backward compatibility is required, consider either (a) introducing a new endpoint (e.g., /provider-variables), (b) adding a query param (e.g., ?format=full|legacy), or (c) returning both shapes (e.g., { mapping: ..., variables: ... }) during a deprecation window.

Suggested change
async def get_model_provider_mapping() -> dict[str, list[dict]]:
"""Return provider variables mapping with full variable info.
Each provider maps to a list of variable objects containing:
- variable_name: Display name shown to user
- variable_key: Environment variable key
- description: Help text for the variable
- required: Whether the variable is required
- is_secret: Whether to treat as credential
- is_list: Whether it accepts multiple values
- options: Predefined options for dropdowns
"""
metadata = get_model_provider_metadata()
return {provider: meta.get("variables", []) for provider, meta in metadata.items()}
async def get_model_provider_mapping(
format: Annotated[
str,
Query(
description="Response format: 'legacy' for simple mapping, 'full' for variable metadata.",
alias="format",
),
] = "legacy",
) -> dict:
"""Return provider variables mapping.
Backwards compatible behavior:
- By default (format=legacy), returns a simple mapping of provider -> variable key,
matching the original endpoint behavior:
{
"openai": "OPENAI_API_KEY",
"anthropic": "ANTHROPIC_API_KEY",
...
}
- When format=full, returns provider -> list of variable metadata objects:
{
"openai": [
{
"variable_name": "...",
"variable_key": "...",
"description": "...",
"required": true,
"is_secret": true,
"is_list": false,
"options": [...]
},
...
],
...
}
"""
if format == "full":
metadata = get_model_provider_metadata()
return {provider: meta.get("variables", []) for provider, meta in metadata.items()}
# Default: legacy simple mapping (provider -> variable key)
return get_model_provider_variable_mapping()

Copilot uses AI. Check for mistakes.
Comment on lines +202 to +203
metadata = get_model_provider_metadata()
return {provider: meta.get("variables", []) for provider, meta in metadata.items()}
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

This endpoint changes its response shape from dict[str, str] (provider → variable key) to dict[str, list[dict]] (provider → variable metadata list). Since the path stayed the same, existing clients expecting the prior schema will break. If backward compatibility is required, consider either (a) introducing a new endpoint (e.g., /provider-variables), (b) adding a query param (e.g., ?format=full|legacy), or (c) returning both shapes (e.g., { mapping: ..., variables: ... }) during a deprecation window.

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jan 26, 2026
Replaces per-variable auto-save with a batch save for all provider variables, improving UX and reducing API calls. Updates input handling to show masked values for secrets, disables save button until all required fields are filled, and provides clearer feedback for configured variables.
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jan 26, 2026
coderabbitai[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions github-actions bot removed the enhancement New feature or request label Jan 26, 2026
lucaseduoli and others added 30 commits February 25, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: [LF] improve compatibility of Langflow Model providers and OpenRAG.

5 participants