Skip to content

feat: add vLLM as a first-class Model Provider with dynamic model discovery#13910

Closed
pareek-ml wants to merge 4 commits into
langflow-ai:mainfrom
pareek-ml:feat/vllm-model-provider
Closed

feat: add vLLM as a first-class Model Provider with dynamic model discovery#13910
pareek-ml wants to merge 4 commits into
langflow-ai:mainfrom
pareek-ml:feat/vllm-model-provider

Conversation

@pareek-ml

@pareek-ml pareek-ml commented Jun 30, 2026

Copy link
Copy Markdown

Summary

Adds vLLM as a first-class Model Provider in Langflow — configure your vLLM server URL once in Settings → Model Providers → vLLM, and all components automatically pick it up, just like Ollama.

Fixes #12771

Why vLLM?

vLLM is one of the most popular open-source LLM serving frameworks for self-hosted inference. Langflow already ships vLLM and vLLM Embeddings components and a registered vLLM icon, but vLLM was absent from Model Providers — users had to manually enter the API base URL in every component instance.

This PR is a clean rebase of #12772 on current main, with all CodeRabbit issues resolved and full test coverage added.

What This Enables

  • Centralized configuration — set VLLM_API_BASE once, all components pick it up
  • Dynamic model discovery — models fetched live from /v1/models (no static catalog needed)
  • LLM + Embeddings — vLLM models appear in both the Language Model dropdown and the Knowledge Base embedding picker
  • Auth optional — local/internal servers work without an API key; authenticated servers pass Authorization: Bearer automatically
  • Fully self-hosted RAG — vLLM embeddings work in the Knowledge Base creation flow

Changes

File Change
src/lfx/.../model_metadata.py Add "vLLM" to LIVE_MODEL_PROVIDERS and MODEL_PROVIDER_METADATA
src/lfx/.../model_utils.py Add fetch_live_vllm_models() — discovery via /v1/models, handles both OpenAI dict and plain list formats, API key auth, /v1 deduplication
src/lfx/.../credentials.py Add vLLM validation with distinct messages for auth (401/403), connection errors, and timeouts
src/lfx/.../class_registry.py Map "vLLM"OpenAIEmbeddings; add "vLLM Embeddings" param mapping
src/lfx/.../instantiation.py Skip API key requirement for vLLM; add base_url wiring for vLLM Embeddings
src/lfx/.../provider_queries.py Include MODEL_PROVIDER_METADATA providers in get_model_providers()
src/backend/.../models.py Ensure metadata-registered providers with no static models appear in API response
src/frontend/.../use-get-model-providers.ts Add vLLM icon mapping
src/frontend/.../providerConstants.ts Add vLLM: "VLLM_API_BASE"
src/frontend/.../modelInputComponent/index.tsx Skip model_type filtering for vLLM
src/frontend/.../ModelSelection.tsx Add vLLM rendering path
src/frontend/.../ProviderList.tsx Allow all model types for vLLM
src/lfx/tests/.../test_vllm_provider.py 31 new unit tests

Design Decisions

  • mapping_field: "vllm_base_url" (contains "base_url") — recognized by get_provider_param_mapping's URL classifier, so base_url_param is correctly wired to downstream consumers in model_catalog.py and flow_preparation.py
  • model_param: "model" — uses the modern langchain_openai.ChatOpenAI parameter (not the deprecated model_name)
  • /v1/models endpoint — correct OpenAI-compatible path; handles the common case where users provide http://host:8000/v1 by checking for the suffix before appending
  • Single fetch for both LLM and embeddings — vLLM's API doesn't distinguish model types, so replace_with_live_models fetches once to avoid duplicates
  • No new LangChain dependency — maps to existing ChatOpenAI (LLM) and OpenAIEmbeddings (embeddings)

Test Coverage

src/lfx/tests/unit/base/models/test_vllm_provider.py — 31 tests, all passing

Covers:

  • Metadata shape and registration (LIVE_MODEL_PROVIDERS, MODEL_PROVIDER_METADATA, EMBEDDING_PROVIDER_CLASS_MAPPING)
  • mapping_field contains "base_url" so the param classifier works
  • get_model_providers() includes vLLM despite no static catalog
  • fetch_live_vllm_models: OpenAI dict format, plain list format, alphabetical sort, /v1 deduplication, auth header forwarding, no-auth path, connection error, timeout, bad payload degradation, LLM/embeddings same output
  • validate_model_provider_key: happy path, correct /v1/models endpoint, API key forwarding, no-auth path, 401, 403, connection error, timeout, /v1 deduplication
  • get_llm does not raise when no API key is set for vLLM

Relationship to #12772

This is a clean reimplementation on current main resolving all issues that prevented #12772 from merging:

  • ✅ Rebased (no merge conflicts)
  • ✅ CodeRabbit issues fixed (mapping_field, model_param, endpoint path, API key forwarding)
  • ✅ Test coverage added (was the only ❌ blocking check)

Summary by CodeRabbit

  • New Features

    • Added support for vLLM across model provider settings, including discovery, selection, and icon display.
    • vLLM models can now appear in provider lists even when they aren’t in the static catalog.
  • Bug Fixes

    • Improved vLLM model filtering so available models show correctly in dropdowns and provider modals.
    • Enhanced provider validation to give clearer error messages for unreachable or unauthorized endpoints.
  • Tests

    • Expanded coverage for vLLM model fetching, provider validation, and embedding/LLM configuration behavior.

…covery

Adds vLLM to Model Providers alongside Ollama, enabling centralized
configuration (configure the server URL once, use everywhere) and
dynamic model discovery via the OpenAI-compatible /v1/models API.

Backend changes:
- Register "vLLM" in LIVE_MODEL_PROVIDERS and MODEL_PROVIDER_METADATA
  with VLLM_API_BASE (required) and VLLM_API_KEY (optional)
- Add fetch_live_vllm_models() for /v1/models discovery with auth header
  forwarding and /v1 deduplication
- Register vLLM in the live-model dispatcher (get_live_models_for_provider)
- Add vLLM single-fetch path in replace_with_live_models (no type distinction)
- Add vLLM credential validation in validate_model_provider_key with
  distinct messages for auth errors, connection errors, and timeouts
- Skip API key requirement for vLLM in get_llm and get_embeddings
- Map "vLLM" to OpenAIEmbeddings in EMBEDDING_PROVIDER_CLASS_MAPPING
- Add "vLLM Embeddings" to EMBEDDING_PARAM_MAPPINGS with base_url wiring
- Add base_url resolution for vLLM Embeddings in get_embeddings
- Ensure metadata-only providers (vLLM) appear in /api/v1/models response
- Include MODEL_PROVIDER_METADATA keys in get_model_providers()

Frontend changes:
- Add vLLM icon mapping in use-get-model-providers.ts
- Add VLLM_API_BASE to PROVIDER_VARIABLE_MAPPING
- Skip model_type filtering for vLLM in modelInputComponent
- Add isVllm rendering path in ModelSelection.tsx
- Allow all model types for vLLM in ProviderList.tsx

Tests:
- 31 unit tests in test_vllm_provider.py covering metadata shape,
  live model fetching (both response formats, URL deduplication, auth
  header forwarding, error degradation), credential validation (happy
  path, 401/403, connection error, timeout, missing URL), and the
  API-key-optional contract

Fixes: langflow-ai#12771
Based on: langflow-ai#12772
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9c141498-1b3e-4d78-a0cf-b377a0f8d90b

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

Adds vLLM as a first-class model provider. The backend registers vLLM in provider metadata, implements live model discovery from /v1/models, adds credential validation, and wires embedding support via OpenAIEmbeddings. The frontend adds the vLLM icon, bypasses model_type filtering for vLLM in dropdowns and modals, and the API surfaces vLLM even when it has no static catalog models.

Changes

vLLM Provider Integration

Layer / File(s) Summary
vLLM provider metadata and registry entries
src/lfx/src/lfx/base/models/model_metadata.py, src/lfx/src/lfx/base/models/unified_models/class_registry.py, src/lfx/src/lfx/base/models/unified_models/provider_queries.py
Adds vLLM to LIVE_MODEL_PROVIDERS and MODEL_PROVIDER_METADATA with VLLM_API_BASE/VLLM_API_KEY variables, icon, and ChatOpenAI mapping. Registers vLLM in EMBEDDING_PROVIDER_CLASS_MAPPING and EMBEDDING_PARAM_MAPPINGS. Updates get_model_providers() to union metadata keys with catalog providers so vLLM appears even without static models.
Live model fetching and provider dispatch
src/lfx/src/lfx/base/models/model_utils.py
Introduces fetch_live_vllm_models to query /v1/models with SSRF validation, optional bearer auth, and flexible payload parsing (OpenAI dict or bare list). Wires into get_live_models_for_provider and special-cases vLLM in replace_with_live_models to fetch once instead of the default llm+embeddings double-fetch.
Credential validation and instantiation guards
src/lfx/src/lfx/base/models/unified_models/credentials.py, src/lfx/src/lfx/base/models/unified_models/instantiation.py
Adds vLLM branch in validate_model_provider_key that GETs /v1/models with optional bearer auth and raises tailored ValueErrors. Broadens the API-key-optional exemption in get_llm and get_embeddings to include vLLM. Adds vLLM Embeddings api_base resolution path in get_embeddings.
Backend API: surfacing metadata-only providers
src/backend/base/langflow/api/v1/models.py
list_models appends entries for providers present in MODEL_PROVIDER_METADATA but absent from filtered_models, seeding icon, api_docs_url, is_configured, and is_enabled.
Frontend icon, dropdown, and modal components
src/frontend/src/controllers/API/queries/models/use-get-model-providers.ts, src/frontend/src/components/core/parameterRenderComponent/components/modelInputComponent/index.tsx, src/frontend/src/modals/modelProviderModal/components/ProviderList.tsx, src/frontend/src/modals/modelProviderModal/components/ModelSelection.tsx
Adds vLLM to the icon map. Bypasses model_type equality filtering for vLLM in ModelInputComponent and ProviderList. ModelSelection adds an isVllm branch that renders a single "Available Models" section instead of the LLM/embeddings split.
vLLM unit tests
src/lfx/tests/unit/base/models/test_vllm_provider.py
New test module covering provider metadata shape, fetch_live_vllm_models URL construction/auth/error handling, live-model dispatch, validate_model_provider_key scenarios, and API-key-optional get_llm/get_embeddings contracts.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Frontend
  participant API as list_models endpoint
  participant Catalog as MODEL_PROVIDER_METADATA
  participant vLLM as vLLM /v1/models

  UI->>API: GET /models
  API->>Catalog: get_model_provider_metadata()
  Catalog-->>API: metadata including vLLM
  API->>vLLM: GET /v1/models (fetch_live_vllm_models)
  vLLM-->>API: model list
  API-->>UI: filtered_models + vLLM entry (is_configured, is_enabled, models)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • langflow-ai/langflow#13185: Adds OpenRouter as a first-class provider using the same model metadata, model_utils dispatch, credentials, instantiation, and frontend icon/listing plumbing modified here.
  • langflow-ai/langflow#13643: Introduces the SSRF-safe HTTP utilities that fetch_live_vllm_models now calls via validate_url_for_ssrf.

Suggested labels

test

Suggested reviewers

  • erichare
  • Cristhianzl
  • ogabrielluiz
🚥 Pre-merge checks | ✅ 4 | ❌ 5

❌ Failed checks (1 warning, 4 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Coverage For New Implementations ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Test Quality And Coverage ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Test File Naming And Structure ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Excessive Mock Usage Warning ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
✅ 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 is concise and accurately summarizes the main vLLM provider integration and dynamic discovery change.
Linked Issues check ✅ Passed The changes cover the linked issue goals: default provider entry, settings config, dynamic discovery, dropdown exposure, embeddings, validation, and tests.
Out of Scope Changes check ✅ Passed The modified files stay focused on vLLM provider support and related UI/backend plumbing, with no clear unrelated feature work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/backend/base/langflow/api/v1/models.py`:
- Around line 203-223: The provider fallback in models.py is bypassing the
existing query-filter contract by appending metadata-only providers even when
model-level filters are active. Update the append logic in the loop that uses
get_model_provider_metadata(), existing_providers, and filtered_models so it
only adds providers when no model-specific filters are present, or re-run the
same filtering criteria from get_unified_models_detailed(...) before appending.
Make sure provider-only fallback still works for empty static-model providers
like vLLM, but /models requests with model_name or metadata filters do not
return empty providers that cannot satisfy the query.

In `@src/frontend/src/constants/providerConstants.ts`:
- Line 33: The vLLM entry in PROVIDER_VARIABLE_MAPPING is incorrectly forcing
the UI to treat VLLM_API_BASE as the synthetic “API Key” fallback in
useProviderConfiguration. Remove this static mapping for vLLM, and let the
provider configuration come from the backend payload instead so the UI can honor
VLLM_API_BASE plus optional VLLM_API_KEY metadata. If vLLM needs special
handling, add an explicit multi-field mapping rather than routing it through the
single secret-field fallback.

In `@src/frontend/src/modals/modelProviderModal/components/ModelSelection.tsx`:
- Line 292: The vLLM branch in ModelSelection is bypassing the same availability
bookkeeping used for metadata.model_type, so availableModels can render while
noModelsAvailable and search visibility still act as if nothing is available.
Update the logic around isVllm, availableModels, and the search/empty-state
checks so the vLLM path treats availableModels.length > 0 as the source of truth
for availability and query matching before branching, keeping the rendered list,
search box, and empty state consistent.

In `@src/lfx/src/lfx/base/models/model_utils.py`:
- Around line 714-722: The models listing request in model_utils uses
VLLM_API_BASE directly in requests.get, which allows user-scoped URLs to probe
arbitrary hosts. Update the model discovery flow around the models_url
construction and requests.get call to use the same SSRF-safe URL
validation/normalization used by the Ollama and LMStudio paths, or add
equivalent allowlist/private-range blocking before any network request is made.
Keep the fix localized to the model utility helper so the base URL is rejected
or sanitized before headers and the GET request are built.

In `@src/lfx/src/lfx/base/models/unified_models/instantiation.py`:
- Around line 476-486: The vLLM Embeddings `api_base` fallback in
`instantiation.py` is looking up provider-specific variables that do not exist
for this provider, so update the `base_url_value` resolution in the `vLLM
Embeddings` branch to use the same source as the main vLLM provider or add a
matching metadata key. Specifically, adjust the `provider_vars =
unified_models_module.get_all_variables_for_provider(...)` and
`_env_if_allowed(...)` lookups so they reference the correct provider symbol and
environment variable names, and keep the assignment into
`kwargs[param_mapping["api_base"]]` unchanged once the right value is resolved.

In `@src/lfx/tests/unit/base/models/test_vllm_provider.py`:
- Around line 14-19: The new test module has Ruff issues that need cleanup: fix
the import ordering/formatting in the module import block, adjust the docstrings
in the test cases to satisfy Ruff’s docstring style rules, and rename the
intentionally unused parameters in the fake_get callbacks to use the
conventional unused prefix. Use the test module’s top-level imports, the
affected test docstrings, and the fake_get helper callbacks as the places to
update so the file becomes lint-clean.
- Around line 496-526: The current test only covers get_llm, so add a companion
contract test for get_embeddings in test_vllm_provider.py to lock down the vLLM
API-key-optional and base-url behavior. Mirror the existing setup pattern by
patching the same unified_models_module helpers and calling get_embeddings with
a vLLM model_selection entry, then assert the embeddings client is built with
the expected arguments and does not require an API key. Use the get_embeddings
symbol alongside get_llm so the test suite covers both changed code paths rather
than only the text-model path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 86f6ad60-2030-4e7f-adbe-c450bafd5efc

📥 Commits

Reviewing files that changed from the base of the PR and between c148617 and ca46cf5.

📒 Files selected for processing (13)
  • src/backend/base/langflow/api/v1/models.py
  • src/frontend/src/components/core/parameterRenderComponent/components/modelInputComponent/index.tsx
  • src/frontend/src/constants/providerConstants.ts
  • src/frontend/src/controllers/API/queries/models/use-get-model-providers.ts
  • src/frontend/src/modals/modelProviderModal/components/ModelSelection.tsx
  • src/frontend/src/modals/modelProviderModal/components/ProviderList.tsx
  • src/lfx/src/lfx/base/models/model_metadata.py
  • src/lfx/src/lfx/base/models/model_utils.py
  • src/lfx/src/lfx/base/models/unified_models/class_registry.py
  • src/lfx/src/lfx/base/models/unified_models/credentials.py
  • src/lfx/src/lfx/base/models/unified_models/instantiation.py
  • src/lfx/src/lfx/base/models/unified_models/provider_queries.py
  • src/lfx/tests/unit/base/models/test_vllm_provider.py

Comment thread src/backend/base/langflow/api/v1/models.py Outdated
Comment thread src/frontend/src/constants/providerConstants.ts Outdated
Comment thread src/lfx/src/lfx/base/models/model_utils.py
Comment thread src/lfx/src/lfx/base/models/unified_models/instantiation.py Outdated
Comment thread src/lfx/tests/unit/base/models/test_vllm_provider.py
Comment thread src/lfx/tests/unit/base/models/test_vllm_provider.py
- Gate metadata-only provider injection in /api/v1/models on absence
  of model-level filters (model_name, tool_calling, etc.) so filtered
  requests don't return empty vLLM entries that cannot satisfy the query
- Remove vLLM from PROVIDER_VARIABLE_MAPPING; let the backend-provided
  multi-field metadata (VLLM_API_BASE + optional VLLM_API_KEY) drive
  the UI instead of the single-secret-field fallback
- Fix ModelSelection.tsx vLLM availability bookkeeping: use
  availableModels.length for noModelsAvailable and apply search query
  filtering via vllmFilteredModels so the search box and empty state
  are consistent
- Add SSRF protection to fetch_live_vllm_models via validate_url_for_ssrf
  before the requests.get call (respects LANGFLOW_SSRF_PROTECTION_ENABLED
  and LANGFLOW_SSRF_ALLOWED_HOSTS)
- Fix vLLM Embeddings base_url resolution in instantiation.py to look up
  provider variables under 'vLLM' (not 'vLLM Embeddings') and use
  VLLM_API_BASE (not the undefined VLLM_EMBEDDINGS_API_BASE)
- Fix all Ruff violations in test_vllm_provider.py (I001 import sort,
  D205/D209/D403 docstring style, ARG001 unused args prefixed with _)
- Add get_embeddings companion test covering the API-key-optional and
  base_url resolution contracts for vLLM Embeddings (32 tests total)
@pareek-ml pareek-ml force-pushed the feat/vllm-model-provider branch from 622ecef to e7e495c Compare June 30, 2026 17:44
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 30, 2026
@pareek-ml

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 30, 2026
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 30, 2026
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 30, 2026
@pareek-ml

Copy link
Copy Markdown
Author

Hey @ogabrielluiz @erichare @Cristhianzl — this PR adds vLLM as a first-class Model Provider (dynamic model discovery, embeddings, credential validation). All 111 CI checks pass and CodeRabbit has no open issues. Would appreciate a review when you get a chance!

erichare added a commit that referenced this pull request Jun 30, 2026
…13910 (#13919)

feat(bundles): add vLLM model-provider bundle (lfx-vllm)

Ships vLLM as a standalone Langflow Extension Bundle built on the
provider-registry seam: its extension.json declares a providers[] entry that
registers a vLLM model provider into the unified model system, with zero core
edits. vLLM is OpenAI-compatible, so the provider reuses ChatOpenAI /
OpenAIEmbeddings and discovers served models live from /v1/models (SSRF-guarded);
the same model is offered for both Language Model and Embedding Model use, and
no API key is required for local servers.

Inherits the original vLLM provider from #13910 by Yash Pareek (@pareek-ml),
reconstructed as a bundle so it no longer edits the 12 core files that PR did.

Co-authored-by: Yash Pareek <yash.pareek@usi.ch>
@pareek-ml

Copy link
Copy Markdown
Author

Superseded by #13919 , which ships vLLM as a standalone bundle without core edits. Closing in favor of it.

@pareek-ml pareek-ml closed this Jun 30, 2026
erichare added a commit that referenced this pull request Jun 30, 2026
* feat(lfx): let extension bundles register model providers

Model providers were hardcoded across lfx core (MODEL_PROVIDER_METADATA, the
class-import registries, LIVE_MODEL_PROVIDERS, and the credential /
instantiation / live-discovery dispatch), so a third party could not add a
provider without editing core -- adding vLLM (#13910) touched 12 files.

Introduce a supported extension point: an extension manifest may declare a
`providers[]` block, which the loader merges into the core provider tables in
place via a new `provider_registry`. Every existing accessor (the lru_cached
variable maps, the shared `model_provider_metadata` reference, the
/api/v1/models surface) then sees a registered provider with no further edits.

- new lfx/base/models/provider_registry.py: ProviderSpec + register_provider
  with core-wins precedence, failure isolation, and a clear() test seam;
  live-discovery and validator callables resolved lazily by dotted path.
- manifest: declarative providers[]; allow a provider-only extension (empty
  bundles); require at least one bundle or provider.
- loader: register manifest providers during load_extension (the startup
  chokepoint), failure-isolated as warnings.
- dispatch seams made registry-aware: get_model_providers union, live-model
  discovery fallback, credential-validation fallback, api-key-optional check.
- zero added cost and byte-identical behavior when no provider bundle is
  installed.

Groundwork for shipping providers as standalone bundles (e.g. lfx-vllm,
superseding #13910).

* feat(lfx): apply registered providers' connection variables generically

get_llm/get_embeddings resolved base_url (and attribution headers) only via
hardcoded per-provider branches, so a bundle-contributed OpenAI-compatible
provider could not point its client at a custom endpoint -- it would silently
hit the default API. Add a generic, is_registered-gated step that applies each
non-secret metadata variable to its declared langchain_param (base_url
localhost-rewritten) or HTTP header, mirroring the core branches. Core
providers keep their explicit branches, so behavior is unchanged.

Completes the provider-bundle seam so an OpenAI-compatible provider (e.g. vLLM)
works fully from a bundle with zero core edits.

* feat(lfx): pass a placeholder api key for key-optional registered providers

langchain_openai's ChatOpenAI / OpenAIEmbeddings raise when constructed with
api_key=None, so an OpenAI-compatible provider that declared
api_key_required=False (e.g. a local vLLM server without auth) would fail to
instantiate even though the model system correctly skips the "API key required"
error. Pass a non-empty "EMPTY" placeholder for such providers so the client
constructs. Only applies to registered (bundle) providers that opted out of
API keys; core providers are unaffected.

* feat(lfx): apply the api key for key-optional registered embedding providers

get_embeddings only passed an API key when the provider's param_mapping
declared an explicit "api_key" slot. Bundle providers can omit that slot, so
apply the resolved key (or the api-key-optional placeholder) under the
OpenAI-compatible "api_key" kwarg for registered providers -- mirroring how
get_llm already resolves the key. Lets an OpenAI-compatible embedding provider
(e.g. vLLM) work from a bundle without that slot.

* feat(bundles): add vLLM model-provider bundle (lfx-vllm) — inherits #13910 (#13919)

feat(bundles): add vLLM model-provider bundle (lfx-vllm)

Ships vLLM as a standalone Langflow Extension Bundle built on the
provider-registry seam: its extension.json declares a providers[] entry that
registers a vLLM model provider into the unified model system, with zero core
edits. vLLM is OpenAI-compatible, so the provider reuses ChatOpenAI /
OpenAIEmbeddings and discovers served models live from /v1/models (SSRF-guarded);
the same model is offered for both Language Model and Embedding Model use, and
no API key is required for local servers.

Inherits the original vLLM provider from #13910 by Yash Pareek (@pareek-ml),
reconstructed as a bundle so it no longer edits the 12 core files that PR did.

Co-authored-by: Yash Pareek <yash.pareek@usi.ch>

* fix(lfx): address CodeRabbit review on the provider seam

- model_utils: normalize non-list live-discovery returns to [] (list[dict] contract)
- provider_registry: validate lazy-import/embedding keys before mutating any
  global table (reject unknown or conflicting model/embedding classes and
  embedding_param_key collisions, so clear() can't drop a core mapping);
  _resolve_callable verifies the target is callable; callable resolution now
  catches broad import-time failures (SyntaxError, side effects) and degrades
  to None
- credentials: normalize non-ValueError bundle-validator failures to ValueError
  so they can't escape as an unhandled 500
- loader: surface skipped (name-collision) provider registrations as a typed
  provider-skipped warning instead of returning silent success
- errors: register provider-invalid / provider-skipped codes + format templates
- tests: cover the register-time warning-isolation and collision paths,
  unknown/conflicting keys, non-callable and non-list discovery, and validator
  normalization

* docs(bundle-api): changelog for the providers[] manifest surface

Manifest providers[] (model-provider registration) and the optional
0-or-1 bundles[] (provider-only extensions) touch in-scope BUNDLE_API
files (manifest.py, _orchestrator.py, errors.py); record the additive
contract change + the new provider-invalid / provider-skipped codes so
the changelog gate passes. No BUNDLE_API_VERSION bump (all additive).

* fix(lfx): correct provider api-key resolution + provider-only discovery

Addresses two review findings on the provider seam:

- [P1] get_model_provider_variable_mapping() fell back to the FIRST provider
  variable when no *required* secret existed, so a provider whose API key is an
  optional secret (e.g. vLLM's VLLM_API_KEY) mapped to its required non-secret
  base URL. get_api_key_for_provider then resolved and forwarded the endpoint as
  the bearer token, skipping the "EMPTY" placeholder. Now prefer a required
  secret, then any secret, then the first variable. Covered by a test that
  exercises the real resolver (no patched stub).
- [P2] discover_installed_extensions / discover_seed_extensions indexed
  manifest.bundles[0], crashing with IndexError on a valid provider-only
  manifest (bundles=[]) and breaking `lfx extension list` / registry discovery.
  Guard the empty-bundle case; DiscoveredExtension.bundle_name and
  registry.Extension.bundle_name are now str | None, and the list CLI renders a
  dash for provider-only extensions.

BUNDLE_API.md changelog updated for the discovery/registry surface nullability.

---------

Co-authored-by: Yash Pareek <yash.pareek@usi.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add vLLM as a default Model Provider

1 participant