723
assert custom_vllm_chat.kwargs["api_key"] == "real-local-key"
724
725
726
+def test_openai_compatible_embedding_keeps_gateway_model_string(monkeypatch):
727
+ """Gateway model ids must reach LiteLLM with an explicit `openai/` provider.
728
+
729
+ An OpenAI-compatible gateway owns its own model namespace, so ids such as
730
+ `nvidia/...` or `auto/embedding` are model names, not provider prefixes.
731
+ Without the prefix LiteLLM re-parses the first segment as a provider and
732
+ either raises "LLM Provider NOT provided" or routes to the wrong provider,
733
+ mangling the model id before the gateway ever sees it.
734
+ """
735
+ monkeypatch.setattr(models, "get_api_key", lambda provider: "None")
736
+
737
+ gateway = "https://gateway.example/v1"
738
+ for model in (
739
+ "nvidia/llama-nemotron-embed-vl-1b-v2:free",
740
+ "openrouter/openai/text-embedding-3-small",
741
+ "auto/embedding",
742
+ ):
743
+ embedding = models.get_embedding_model(
744
+ "other", model, api_base=gateway, api_key="gateway-key"
745
+ )
746
+ assert embedding.model_name == f"openai/{model}"
747
+ assert embedding.kwargs["api_base"] == gateway
748
+
749
+ # The bundled OpenRouter embedding provider is affected the same way: it
750
+ # resolves to litellm_provider `openai` against OpenRouter's api_base, so an
751
+ # OpenRouter-style id has to survive intact. Previously `openai/<model>` was
752
+ # handed to LiteLLM bare, which consumed the `openai/` segment and forwarded
753
+ # only `<model>` to OpenRouter.
754
+ for model in (
755
+ "openai/text-embedding-3-small",
756
+ "nvidia/llama-nemotron-embed-vl-1b-v2:free",
757
+ ):
758
+ openrouter_embedding = models.get_embedding_model("openrouter", model)
759
+ assert openrouter_embedding.model_name == f"openai/{model}"
760
+ assert openrouter_embedding.kwargs["api_base"] == "https://openrouter.ai/api/v1"
761
+
762
+ # Plain OpenAI behaviour is unchanged: LiteLLM strips the `openai/` prefix
763
+ # and forwards the bare model id, exactly as it did without a prefix.
764
+ openai_embedding = models.get_embedding_model("openai", "text-embedding-3-small")
765
+ assert openai_embedding.model_name == "openai/text-embedding-3-small"
766
+
767
+ # Providers that do not resolve to `openai` keep their existing prefix.
768
+ ollama_embedding = models.get_embedding_model("ollama", "nomic-embed-text")
769
+ assert ollama_embedding.model_name == "ollama/nomic-embed-text"
770
+
771
+
772
def test_embedding_config_repairs_sentence_transformer_aliases(monkeypatch):
773
from plugins._model_config.helpers import model_config
774