diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json index fcc6aac1c14..e24e5b21583 100644 --- a/litellm/proxy/public_endpoints/provider_create_fields.json +++ b/litellm/proxy/public_endpoints/provider_create_fields.json @@ -2062,6 +2062,44 @@ ], "default_model_placeholder": "gpt-3.5-turbo" }, + { + "provider": "NVIDIA_RIVA", + "provider_display_name": "Nvidia Riva", + "litellm_provider": "nvidia_riva", + "credential_fields": [ + { + "key": "api_base", + "label": "API Base", + "placeholder": "grpc.nvcf.nvidia.com:443", + "tooltip": "host:port of the Riva gRPC endpoint. Use grpc.nvcf.nvidia.com:443 for NVCF-hosted Riva, or your own host (e.g. localhost:50051) when self-hosting. Riva has no public default, so this is required.", + "required": true, + "field_type": "text", + "options": null, + "default_value": null + }, + { + "key": "api_key", + "label": "API Key", + "placeholder": "nvapi-...", + "tooltip": "Sent as gRPC authorization metadata. Required for NVCF-hosted Riva, optional for self-hosted deployments without auth.", + "required": false, + "field_type": "password", + "options": null, + "default_value": null + }, + { + "key": "nvcf_function_id", + "label": "NVCF Function ID", + "placeholder": "1598d209-5e27-4d3c-8079-4751568b1081", + "tooltip": "NVCF function id of the hosted Riva model. Setting it turns on TLS and the function-id gRPC metadata. Leave empty for self-hosted Riva.", + "required": false, + "field_type": "text", + "options": null, + "default_value": null + } + ], + "default_model_placeholder": "nvidia_riva/nvidia/parakeet-ctc-1_1b-asr" + }, { "provider": "Ollama", "provider_display_name": "Ollama", diff --git a/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py b/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py index 88dc07e741b..e99bdfb5c35 100644 --- a/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py +++ b/tests/test_litellm/proxy/public_endpoints/test_public_endpoints.py @@ -243,6 +243,34 @@ def test_bedrock_mantle_provider_fields(): assert fields_by_key["api_base"]["field_type"] == "text" +def test_nvidia_riva_provider_fields(): + app_instance = FastAPI() + app_instance.include_router(router) + test_client = TestClient(app_instance) + + response = test_client.get("/public/providers/fields") + assert response.status_code == 200 + providers = response.json() + + riva = next((p for p in providers if p["provider"] == "NVIDIA_RIVA"), None) + assert riva is not None, "NVIDIA Riva provider entry not found" + + assert riva["provider_display_name"] == "Nvidia Riva" + assert riva["litellm_provider"] == LlmProviders.NVIDIA_RIVA.value + assert riva["default_model_placeholder"].startswith("nvidia_riva/") + + fields_by_key = {f["key"]: f for f in riva["credential_fields"]} + + assert fields_by_key["api_base"]["required"] is True + assert fields_by_key["api_base"]["field_type"] == "text" + + assert fields_by_key["api_key"]["required"] is False + assert fields_by_key["api_key"]["field_type"] == "password" + + assert "nvcf_function_id" in fields_by_key + assert fields_by_key["nvcf_function_id"]["required"] is False + + def test_google_ai_studio_provider_fields_expose_api_base(): """The Google AI Studio (gemini) credential form must let admins set a custom api_base so they can point at a Gemini-compatible gateway (e.g. a self-hosted diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx index 777cdc62987..b163a6b341c 100644 --- a/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx +++ b/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx @@ -94,6 +94,14 @@ describe("provider_info_helpers", () => { expect(result.displayName).toBe(Providers.ZAI); }); + it("should resolve the nvidia_riva provider value to the Nvidia Riva display name and logo", () => { + const result = getProviderLogoAndName("nvidia_riva"); + expect(result.displayName).toBe(Providers.NVIDIA_RIVA); + expect(provider_map.NVIDIA_RIVA).toBe("nvidia_riva"); + expect(result.logo).toBe(providerLogoMap[Providers.NVIDIA_RIVA]); + expect(result.logo).toBeTruthy(); + }); + it("should return provider value as display name when no mapping exists", () => { const unknownProvider = "unknown_provider"; const result = getProviderLogoAndName(unknownProvider); @@ -225,6 +233,15 @@ describe("provider_info_helpers", () => { expect(getPlaceholder(Providers.ZAI)).toBe("zai/glm-4.5"); }); + it("should return the riva asr placeholder for NVIDIA_RIVA provider", () => { + expect(getPlaceholder(Providers.NVIDIA_RIVA)).toBe("nvidia_riva/nvidia/parakeet-ctc-1_1b-asr"); + }); + + it("should resolve enum keys from the provider dropdown, not just enum values", () => { + expect(getPlaceholder("NVIDIA_RIVA")).toBe("nvidia_riva/nvidia/parakeet-ctc-1_1b-asr"); + expect(getPlaceholder("WATSONX")).toBe("watsonx/ibm/granite-3-3-8b-instruct"); + }); + it("should return default gpt-3.5-turbo placeholder for unknown provider", () => { expect(getPlaceholder("UnknownProvider" as any)).toBe("gpt-3.5-turbo"); }); diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx index fa6b3c79230..ae311070c07 100644 --- a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx +++ b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx @@ -130,6 +130,7 @@ export enum Providers { NOVITA = "Novita", NSCALE = "Nscale", NVIDIA_NIM = "Nvidia Nim", + NVIDIA_RIVA = "Nvidia Riva", Ollama = "Ollama", OLLAMA_CHAT = "Ollama Chat", OOBABOOGA = "Oobabooga", @@ -238,6 +239,7 @@ export const provider_map: Record = { NOVITA: "novita", NSCALE: "nscale", NVIDIA_NIM: "nvidia_nim", + NVIDIA_RIVA: "nvidia_riva", Ollama: "ollama", OLLAMA_CHAT: "ollama_chat", OOBABOOGA: "oobabooga", @@ -334,6 +336,7 @@ export const providerLogoMap: Partial> = { [Providers.NEBIUS]: nebiusLogo.src, [Providers.NOVITA]: novitaLogo.src, [Providers.NVIDIA_NIM]: nvidiaNimLogo.src, + [Providers.NVIDIA_RIVA]: nvidiaNimLogo.src, [Providers.Ollama]: ollamaLogo.src, [Providers.OLLAMA_CHAT]: ollamaLogo.src, [Providers.OOBABOOGA]: openaiSmallLogo.src, @@ -400,48 +403,32 @@ export const getProviderLogoAndName = (providerValue: string): { logo: string; d return { logo, displayName }; }; +const providerPlaceholderMap: Partial> = { + [Providers.AIML]: "aiml/flux-pro/v1.1", + [Providers.Anthropic]: "claude-3-opus", + [Providers.Azure]: "my-deployment", + [Providers.Azure_AI_Studio]: "azure_ai/command-r-plus", + [Providers.Bedrock]: "claude-3-opus", + [Providers.Cursor]: "cursor/claude-4-sonnet", + [Providers.DeepInfra]: "deepinfra/", + [Providers.FalAI]: "fal_ai/fal-ai/flux-pro/v1.1-ultra", + [Providers.Google_AI_Studio]: "gemini-pro", + [Providers.JinaAI]: "jina_ai/", + [Providers.NVIDIA_RIVA]: "nvidia_riva/nvidia/parakeet-ctc-1_1b-asr", + [Providers.Oracle]: "oci/xai.grok-4", + [Providers.RunwayML]: "runwayml/gen4_turbo", + [Providers.SageMaker]: "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b", + [Providers.Snowflake]: "snowflake/mistral-7b", + [Providers.Vertex_AI]: "gemini-pro", + [Providers.VolcEngine]: "volcengine/", + [Providers.Voyage]: "voyage/", + [Providers.WATSONX]: "watsonx/ibm/granite-3-3-8b-instruct", + [Providers.ZAI]: "zai/glm-4.5", +}; + export const getPlaceholder = (selectedProvider: string): string => { - if (selectedProvider === Providers.AIML) { - return "aiml/flux-pro/v1.1"; - } else if (selectedProvider === Providers.Vertex_AI) { - return "gemini-pro"; - } else if (selectedProvider == Providers.Anthropic) { - return "claude-3-opus"; - } else if (selectedProvider == Providers.Bedrock) { - return "claude-3-opus"; - } else if (selectedProvider == Providers.SageMaker) { - return "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b"; - } else if (selectedProvider == Providers.Google_AI_Studio) { - return "gemini-pro"; - } else if (selectedProvider == Providers.Azure_AI_Studio) { - return "azure_ai/command-r-plus"; - } else if (selectedProvider == Providers.Azure) { - return "my-deployment"; - } else if (selectedProvider == Providers.Oracle) { - return "oci/xai.grok-4"; - } else if (selectedProvider == Providers.Snowflake) { - return "snowflake/mistral-7b"; - } else if (selectedProvider == Providers.Voyage) { - return "voyage/"; - } else if (selectedProvider == Providers.JinaAI) { - return "jina_ai/"; - } else if (selectedProvider == Providers.VolcEngine) { - return "volcengine/"; - } else if (selectedProvider == Providers.DeepInfra) { - return "deepinfra/"; - } else if (selectedProvider == Providers.FalAI) { - return "fal_ai/fal-ai/flux-pro/v1.1-ultra"; - } else if (selectedProvider == Providers.RunwayML) { - return "runwayml/gen4_turbo"; - } else if (selectedProvider === Providers.WATSONX) { - return "watsonx/ibm/granite-3-3-8b-instruct"; - } else if (selectedProvider === Providers.Cursor) { - return "cursor/claude-4-sonnet"; - } else if (selectedProvider === Providers.ZAI) { - return "zai/glm-4.5"; - } else { - return "gpt-3.5-turbo"; - } + const resolvedProvider = Providers[selectedProvider as keyof typeof Providers] ?? (selectedProvider as Providers); + return providerPlaceholderMap[resolvedProvider] ?? "gpt-3.5-turbo"; }; export const getProviderModels = (provider: Providers, modelMap: any): Array => {