diff --git a/litellm/types/proxy/guardrails/guardrail_hooks/generic_guardrail_api.py b/litellm/types/proxy/guardrails/guardrail_hooks/generic_guardrail_api.py index d38e54986b9..f1bac1becfd 100644 --- a/litellm/types/proxy/guardrails/guardrail_hooks/generic_guardrail_api.py +++ b/litellm/types/proxy/guardrails/guardrail_hooks/generic_guardrail_api.py @@ -130,6 +130,14 @@ class GenericGuardrailAPIConfigModel( ): """Configuration parameters for the Generic Guardrail API guardrail""" + api_base: str | None = Field( + default=None, + description="Base URL of the guardrail endpoint to call (e.g. http://llm-guard:8000/analyze). Required when creating the guardrail: without it there is nowhere to send the request.", + ) + api_key: str | None = Field( + default=None, + description="API key sent to the guardrail endpoint. Optional; omit it when the endpoint does not authenticate the caller.", + ) optional_params: GenericGuardrailAPIOptionalParams | None = Field( default_factory=GenericGuardrailAPIOptionalParams, description="Optional parameters for the Generic Guardrail API guardrail", diff --git a/tests/unit/proxy/guardrails/guardrail_hooks/test_generic_guardrail_api.py b/tests/unit/proxy/guardrails/guardrail_hooks/test_generic_guardrail_api.py index 8308a7ba386..69cb6827715 100644 --- a/tests/unit/proxy/guardrails/guardrail_hooks/test_generic_guardrail_api.py +++ b/tests/unit/proxy/guardrails/guardrail_hooks/test_generic_guardrail_api.py @@ -1545,6 +1545,26 @@ class TestGenericGuardrailAPIStreamingConfig: assert GenericGuardrailAPI.get_config_model() is GenericGuardrailAPIConfigModel + def test_config_model_declares_connection_fields(self): + """The dashboard builds a provider's form from this model. + + ``get_provider_specific_params`` renders whatever the config model + declares, and the form only offers those keys, so ``api_base`` and + ``api_key`` have to be fields here even though the initializer reads + them off ``litellm_params`` at runtime. Without them the provider shows + no configuration fields at all (BerriAI/litellm#34927). + """ + from litellm.types.proxy.guardrails.guardrail_hooks.generic_guardrail_api import ( + GenericGuardrailAPIConfigModel, + ) + + fields = GenericGuardrailAPIConfigModel.model_json_schema().get("properties", {}) + + for field_name in ("api_base", "api_key"): + assert field_name in fields, f"{field_name} must be a config model field" + assert fields[field_name].get("description"), f"{field_name} needs a description for the form" + assert field_name not in GenericGuardrailAPIConfigModel.model_json_schema().get("required", []) + def test_streaming_transform_mode_defaults_block_only(self): guardrail = GenericGuardrailAPI( api_base="https://api.test.guardrail.com",