diff --git a/litellm/utils.py b/litellm/utils.py index a7d7447d7f3..a0158777ea8 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -10012,6 +10012,19 @@ class ProviderConfigManager: if VertexAIPartnerModels.is_vertex_partner_model(model): return None + ######################################################### + # Model Garden publisher models served via the OpenAI-compatible + # route (e.g. xai/grok-*) are not Vertex Partner "raw" models, but + # they still go through the litellm.completion() adapter (which + # dispatches them to the Model Garden OpenAI-compatible handler), + # never through the Google Gen AI config. Without this case the + # unified Gemini-style endpoint POST /v1beta/models/{model}:generateContent + # would treat e.g. vertex_ai/xai/grok-* as a native Gemini model + # and fail with a protocol mismatch. + ######################################################### + if model.startswith("xai/"): + return None + ######################################################### # If the model is not a Vertex Partner model, return the Vertex AI Google Gen AI Config # This is for Vertex `gemini` models diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index a72aec07766..a35f3e2d549 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -6447,6 +6447,53 @@ def test_calculate_max_parallel_requests_precedence( ) +def test_get_provider_google_genai_generate_content_config_vertex_partner_models(): + """ + https://github.com/BerriAI/litellm/issues/41835 + Vertex Grok (vertex_ai/xai/grok-*) is rejected on /v1beta/models/{model}:generateContent + because get_provider_google_genai_generate_content_config() only falls back to the + litellm.completion() adapter for Vertex Partner models, and xai/ was missing from + PartnerModelPrefixes. Ensure xai/grok-* now returns None (i.e. the generateContent + endpoint routes it through the chat-completions adapter like other Model Garden + OpenAI-compatible partners), while gemini models still get the native config. + """ + from litellm.types.utils import LlmProviders + + # Grok via Model Garden -> through the completion adapter (None) + assert ( + ProviderConfigManager.get_provider_google_genai_generate_content_config( + model="xai/grok-4.6", provider=LlmProviders.VERTEX_AI + ) + is None + ) + assert ( + ProviderConfigManager.get_provider_google_genai_generate_content_config( + model="xai/grok-4.1-fast-non-reasoning", provider=LlmProviders.VERTEX_AI + ) + is None + ) + + # Other existing partner models are unaffected + assert ( + ProviderConfigManager.get_provider_google_genai_generate_content_config( + model="claude-3-5-sonnet-20241022", provider=LlmProviders.VERTEX_AI + ) + is None + ) + + # Native Gemini models still get the Vertex Google Gen AI config + from litellm.llms.vertex_ai.google_genai.transformation import ( + VertexAIGoogleGenAIConfig, + ) + + assert isinstance( + ProviderConfigManager.get_provider_google_genai_generate_content_config( + model="gemini-1.5-pro", provider=LlmProviders.VERTEX_AI + ), + VertexAIGoogleGenAIConfig, + ) + + class _NamedStream(io.BytesIO): def __init__(self, name: str | int) -> None: super().__init__(b"%PDF-1.4 secret document body")