From f46ed3728baf63f3d0e7bdd938700d809d01ffaa Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Wed, 19 Aug 2026 15:50:29 +0800 Subject: [PATCH] Fix LlamaIndexHook docs to stop claiming Ollama/vLLM support The class docstring, the host field description, and the UI placeholder said host= could point LlamaIndexHook at Ollama or vLLM. get_llm() and get_embedding_model() return LlamaIndex's OpenAI / OpenAIEmbedding classes, which validate model= client-side against LlamaIndex's OpenAI-only model-name allowlists before any request is sent, so an Ollama/vLLM model name is rejected regardless of host. Document the real constraint and why it exists instead of the non-existent Ollama/vLLM support. --- providers/common/ai/docs/hooks/llamaindex.rst | 15 +++++++++++-- .../common/ai/docs/self_hosted_models.rst | 19 +++++++++++++---- providers/common/ai/provider.yaml | 4 +--- .../providers/common/ai/get_provider_info.py | 4 ++-- .../providers/common/ai/hooks/llamaindex.py | 21 ++++++++++++++++--- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/providers/common/ai/docs/hooks/llamaindex.rst b/providers/common/ai/docs/hooks/llamaindex.rst index 2bbd779ed56d1..cad520c014dc1 100644 --- a/providers/common/ai/docs/hooks/llamaindex.rst +++ b/providers/common/ai/docs/hooks/llamaindex.rst @@ -33,6 +33,16 @@ singleton. Operators pass the resolved model directly to LlamaIndex constructors, so concurrent tasks in the same worker don't race on shared state. +``get_llm()`` and ``get_embedding_model()`` return LlamaIndex's ``OpenAI`` / +``OpenAIEmbedding`` classes, which validate ``model=`` client-side against +LlamaIndex's OpenAI-only model-name allowlists before any request is sent. +Pointing **host** at an Ollama or vLLM endpoint does not add support for +those backends: their model names (e.g. ``llama3.2``) are never in the +OpenAI allowlist, so the call fails on the model name, not on connectivity. +``get_embedding_model()`` raises immediately at construction; +``get_llm()`` defers the error until the first call that reads +``.metadata`` (``.chat()`` / ``.complete()``). + OpenAI by default, BYO for other vendors ---------------------------------------- @@ -73,8 +83,9 @@ The hook reads credentials from the Airflow connection of type ``llamaindex``: - **password** -- API key (passed as ``api_key`` to ``OpenAIEmbedding`` / ``OpenAI``). -- **host** -- Optional base URL (passed as ``api_base``; useful for custom - OpenAI-compatible endpoints, Ollama, vLLM). +- **host** -- Optional base URL (passed as ``api_base``). Only useful for + an OpenAI-compatible proxy that accepts OpenAI's exact model names (e.g. + an internal gateway) -- not Ollama or vLLM (see above). - **extra** JSON -- ``{"embed_model": "text-embedding-3-small", "llm_model": "gpt-4o"}`` -- default model identifiers stored on the connection. diff --git a/providers/common/ai/docs/self_hosted_models.rst b/providers/common/ai/docs/self_hosted_models.rst index 8919051683b80..ccef68e754421 100644 --- a/providers/common/ai/docs/self_hosted_models.rst +++ b/providers/common/ai/docs/self_hosted_models.rst @@ -339,10 +339,13 @@ OpenAI-compatible endpoint the same way as the vLLM example above. Cross-hook naming differences ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:class:`~airflow.providers.common.ai.hooks.langchain.LangChainHook` and -:class:`~airflow.providers.common.ai.hooks.llamaindex.LlamaIndexHook` also -support self-hosted endpoints through the same ``host`` connection field, but -the underlying constructor keyword each hook passes it to is not uniform: +:class:`~airflow.providers.common.ai.hooks.langchain.LangChainHook` also +supports self-hosted endpoints through the same ``host`` connection field, +forwarding it to the same constructor keyword as ``PydanticAIHook``. +:class:`~airflow.providers.common.ai.hooks.llamaindex.LlamaIndexHook` accepts +``host`` too, but forwards it to a different keyword -- and, unlike the other +two, does not actually support self-hosted models (see the note after the +table): .. list-table:: :header-rows: 1 @@ -360,6 +363,14 @@ the underlying constructor keyword each hook passes it to is not uniform: - ``host`` - ``api_base`` +``LlamaIndexHook`` does **not** support Ollama or vLLM: ``get_llm()`` and +``get_embedding_model()`` return LlamaIndex's ``OpenAI`` / ``OpenAIEmbedding`` +classes, which validate ``model=`` client-side against LlamaIndex's +OpenAI-only model-name allowlists, so a self-hosted model name is rejected +before any request reaches ``host``. Only an OpenAI-compatible proxy that +accepts OpenAI's exact model names works. See :doc:`hooks/llamaindex` for +details. + Where to go next ------------------- diff --git a/providers/common/ai/provider.yaml b/providers/common/ai/provider.yaml index c221691f8354e..b53894d288bc0 100644 --- a/providers/common/ai/provider.yaml +++ b/providers/common/ai/provider.yaml @@ -445,8 +445,6 @@ connection-types: connection-type: llamaindex external-services: - OpenAI - - Ollama - - vLLM ui-field-behaviour: hidden-fields: - schema @@ -455,7 +453,7 @@ connection-types: relabeling: password: API Key placeholders: - host: "https://api.openai.com/v1 (optional, for custom endpoints / Ollama)" + host: "https://api.openai.com/v1 (optional, for an OpenAI-compatible proxy)" extra: '{"embed_model": "text-embedding-3-small", "llm_model": "gpt-4o"}' conn-fields: embed_model: diff --git a/providers/common/ai/src/airflow/providers/common/ai/get_provider_info.py b/providers/common/ai/src/airflow/providers/common/ai/get_provider_info.py index 46441b2bf6613..4aa7da1a98aa9 100644 --- a/providers/common/ai/src/airflow/providers/common/ai/get_provider_info.py +++ b/providers/common/ai/src/airflow/providers/common/ai/get_provider_info.py @@ -358,12 +358,12 @@ def get_provider_info(): "hook-class-name": "airflow.providers.common.ai.hooks.llamaindex.LlamaIndexHook", "hook-name": "LlamaIndex", "connection-type": "llamaindex", - "external-services": ["OpenAI", "Ollama", "vLLM"], + "external-services": ["OpenAI"], "ui-field-behaviour": { "hidden-fields": ["schema", "port", "login"], "relabeling": {"password": "API Key"}, "placeholders": { - "host": "https://api.openai.com/v1 (optional, for custom endpoints / Ollama)", + "host": "https://api.openai.com/v1 (optional, for an OpenAI-compatible proxy)", "extra": '{"embed_model": "text-embedding-3-small", "llm_model": "gpt-4o"}', }, }, diff --git a/providers/common/ai/src/airflow/providers/common/ai/hooks/llamaindex.py b/providers/common/ai/src/airflow/providers/common/ai/hooks/llamaindex.py index 354e12afe4534..f0e2abd9bcdd5 100644 --- a/providers/common/ai/src/airflow/providers/common/ai/hooks/llamaindex.py +++ b/providers/common/ai/src/airflow/providers/common/ai/hooks/llamaindex.py @@ -58,11 +58,26 @@ class LlamaIndexHook(BaseHook): to LlamaIndex constructors so concurrent tasks in the same worker don't race on shared state. + .. note:: + + ``get_llm()`` and ``get_embedding_model()`` return LlamaIndex's + ``OpenAI`` / ``OpenAIEmbedding`` classes, which validate ``model=`` + client-side against LlamaIndex's OpenAI-only model-name allowlists + before any request is sent. Pointing **host** at an Ollama or vLLM + endpoint does not add support for those backends: their model names + (e.g. ``llama3.2``) are never in the OpenAI allowlist, so the call + still fails on the model name, not on connectivity. + ``get_embedding_model()`` raises immediately at construction; + ``get_llm()`` defers the error until the first call that reads + ``.metadata`` (``.chat()`` / ``.complete()``). + Connection fields: * **password**: API key passed as ``api_key=``. - * **host**: Optional base URL passed as ``api_base=`` (custom endpoints, - Ollama, vLLM). + * **host**: Optional base URL passed as ``api_base=``. Only useful for + an OpenAI-compatible proxy that accepts OpenAI's exact model names + (e.g. an internal gateway) -- not Ollama or vLLM, whose model + catalogs are rejected regardless of ``host`` (see note above). * **extra** JSON: ``{"embed_model": "text-embedding-3-small", "llm_model": "gpt-4o"}`` -- default model identifiers stored on the connection. @@ -108,7 +123,7 @@ def get_ui_field_behaviour() -> dict[str, Any]: "hidden_fields": ["schema", "port", "login"], "relabeling": {"password": "API Key"}, "placeholders": { - "host": "https://api.openai.com/v1 (optional, for custom endpoints / Ollama)", + "host": "https://api.openai.com/v1 (optional, for an OpenAI-compatible proxy)", "extra": '{"embed_model": "text-embedding-3-small", "llm_model": "gpt-4o"}', }, }