diff --git a/litellm/main.py b/litellm/main.py index 8b239c454f..cb3ddc2f40 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -4680,12 +4680,16 @@ def embedding( # noqa: PLR0915 if dynamic_api_key is not None: api_key = dynamic_api_key + allowed_openai_params: Optional[List[str]] = kwargs.get( + "allowed_openai_params", None + ) optional_params = get_optional_params_embeddings( model=model, user=user, dimensions=dimensions, encoding_format=encoding_format, custom_llm_provider=custom_llm_provider, + allowed_openai_params=allowed_openai_params, **non_default_params, ) diff --git a/litellm/utils.py b/litellm/utils.py index 7ac828aefc..81e772b176 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -3117,6 +3117,7 @@ def get_optional_params_embeddings( # noqa: PLR0915 custom_llm_provider="", drop_params: Optional[bool] = None, additional_drop_params: Optional[List[str]] = None, + allowed_openai_params: Optional[List[str]] = None, **kwargs, ): # Lazy load get_supported_openai_params @@ -3131,6 +3132,7 @@ def get_optional_params_embeddings( # noqa: PLR0915 drop_params = passed_params.pop("drop_params", None) additional_drop_params = passed_params.pop("additional_drop_params", None) + allowed_openai_params = passed_params.pop("allowed_openai_params", None) or [] # Remove function objects from passed_params to avoid JSON serialization errors passed_params.pop("get_supported_openai_params", None) @@ -3188,11 +3190,11 @@ def get_optional_params_embeddings( # noqa: PLR0915 ## raise exception if non-default value passed for non-openai/azure embedding calls elif custom_llm_provider == "openai": # 'dimensions` is only supported in `text-embedding-3` and later models - if ( model is not None and "text-embedding-3" not in model and "dimensions" in non_default_params.keys() + and "dimensions" not in (allowed_openai_params or []) ): raise UnsupportedParamsError( status_code=500, diff --git a/tests/local_testing/test_get_optional_params_embeddings.py b/tests/local_testing/test_get_optional_params_embeddings.py index 055be48755..8a94c8f468 100644 --- a/tests/local_testing/test_get_optional_params_embeddings.py +++ b/tests/local_testing/test_get_optional_params_embeddings.py @@ -69,3 +69,40 @@ def test_bedrock_embed_v2_with_drop_params(): ) print(f"received optional_params: {optional_params}") assert optional_params == {"dimensions": 512, "embeddingTypes": ["binary"]} + + +def test_openai_non_text_embedding_3_with_allowed_openai_params(): + """ + Test that `dimensions` is allowed for non-text-embedding-3 OpenAI models + when `allowed_openai_params=["dimensions"]` is passed. Without this flag, + an UnsupportedParamsError would be raised. + """ + model, custom_llm_provider, _, _ = get_llm_provider( + model="openai/nvidia/llama-3.2-nv-embedqa-1b-v2" + ) + optional_params = get_optional_params_embeddings( + model=model, + dimensions=1024, + custom_llm_provider=custom_llm_provider, + allowed_openai_params=["dimensions"], + ) + print(f"received optional_params: {optional_params}") + assert optional_params.get("dimensions") == 1024 + + +def test_openai_non_text_embedding_3_without_allowed_openai_params_raises(): + """ + Test that passing `dimensions` to a non-text-embedding-3 OpenAI model + without `allowed_openai_params` still raises UnsupportedParamsError. + """ + from litellm.exceptions import UnsupportedParamsError + + model, custom_llm_provider, _, _ = get_llm_provider( + model="openai/nvidia/llama-3.2-nv-embedqa-1b-v2" + ) + with pytest.raises(UnsupportedParamsError): + get_optional_params_embeddings( + model=model, + dimensions=1024, + custom_llm_provider=custom_llm_provider, + )