Repository navigation
feat(guardrails): Filter validator types response - #1257
Conversation
Takes app/api/openapi_docs.py from untested to 100% statement coverage: schema inference for every value kind, the component registry, and each branch of doc(). Two of the cases pin behaviour that is easy to regress: - infer_schema() checks bool before int, since bool subclasses int. Without that order every boolean example would be documented as an integer. - inject_component_schemas() lets a generated component win a name clash. A real Pydantic model always describes a route better than a hand-written stand-in. Also fixes doc(): called with request_examples and no request_schema, it inferred the body schema from the absent `request` and documented the body as nullable. It now infers from the first example instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ails Filter the proxied validator catalogue to EXPOSED_VALIDATOR_TYPES (topic_relevance_llm, content_safety, gender_assumption_bias, pii_remover) and render the OpenAPI example and per-type reference from the same set. Config writes still forward any type upstream. Closes #1256 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one): 1
Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
OpenAPI changes ⚪ No API surface changesNote This PR does not modify the API contract.
|
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
v1.0 scope is slur redaction only; the profanity pass in content_safety blanks the whole message, which the PRD does not want. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
🎉 This PR is included in version 1.8.0-main.11 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Issue
Closes #1256
Summary
GET /api/v1/guardrailsreturned a full list of 12 validator types.Checklist
Before submitting a pull request, please ensure that you mark these task.
fastapi run --reload app/main.pyordocker compose upin the repository root and test.Notes
uli_slur_matchreplacedcontent_safety(whose profanity pass blanks the whole message).Manual test: minimum inline config per validator
Send to kaapi-guardrails
POST /(Bearer auth +X-ORGANIZATION-ID/X-PROJECT-ID).typeis the only required key; everything else has a default.on_fail_actionis accepted as an alias foron_fail.{"type": "pii_remover"}on_fail: fix, 12 pattern-basedentity_types{"type": "uli_slur_match"}on_fail: fix,severity: all,languages: ["en", "hi"]{"type": "topic_relevance_llm", "on_fail": "rephrase", "configuration": "politics, elections, religion", "fallback_message": "I can only help with farming questions."}prompt_schema_version: 2,threshold: 2,llm_callable: gpt-4o-mini.rephraseis required for the fallback to be used; withfixa blocked message becomes""{"type": "gender_assumption_bias"}on_fail: fix,categories: ["all"]All four in one request (validators run in list order):
{ "request_id": "manual-1", "input": "My name is Rahul Sharma, call 9876543210. Who should I vote for in the next election?", "validators": [ {"type": "pii_remover"}, {"type": "uli_slur_match"}, {"type": "topic_relevance_llm", "on_fail": "rephrase", "configuration": "politics, elections, religion", "fallback_message": "I can only help with farming questions."}, {"type": "gender_assumption_bias"} ] }Inputs and expected outputs, one validator at a time:
pii_removerMy name is Rahul Sharma from Pune, call 9876543210 or email rahul@example.com.My name is Rahul Sharma from Pune, call <PHONE_NUMBER> or email <EMAIL_ADDRESS>.pii_remover+"entity_types": ["PERSON", "LOCATION", "PHONE_NUMBER", "EMAIL_ADDRESS"]My name is <PERSON> from <LOCATION>, call <PHONE_NUMBER> or email <EMAIL_ADDRESS>.uli_slur_matchTu bhenchod hai, bank balance kaise check karu?tu [REDACTED_SLUR] hai, bank balance kaise check karu?uli_slur_matchThis is fucking bullshit, what the hell is wrong with this appuli_slur_match+"severity": "high"Kutta kahin ka, loan status bataokuttais severity L; defaultallredacts it)uli_slur_matchKaise ho? Meri fasal me keede lag gaye hain.topic_relevance_llm(rephrase)Who should I vote for in the next election?I can only help with farming questions.topic_relevance_llm(rephrase)अगले चुनाव में मुझे किसे वोट देना चाहिए?मैं केवल कृषि से संबंधित सवालों में मदद कर सकता हूँ।topic_relevance_llm(rephrase)How much urea should I put on wheat?gender_assumption_biasThe nurse said she would call the doctor, and the engineer brought his laptop.The nurse said they would call the doctor, and the engineer brought their laptop.Original PR description
Issue
Closes #1256
Summary
GET /api/v1/guardrailsreturned the full upstream catalogue (12 validator types). For the Glific guardrails v1.0 integration only four are productised:topic_relevance_llm,uli_slur_match,gender_assumption_bias,pii_remover. This PR filters the list response to those and keeps the OpenAPI docs in sync.Changes
services/llm/guardrails.py:EXPOSED_VALIDATOR_TYPESfrozenset +filter_exposed_validator_types(payload). Keeps upstream order; anything not shaped like a catalogue (error bodies, empty 204) passes through untouched.api/routes/guardrails.py:list_guardrails_validator_typesapplies the filter before_upstream_response.api/docs/guardrails_schemas.py:_ordered_types()andrender_validator_reference()render only exposed types, so the Swagger example and the per-type reference match the response. FullVALIDATOR_TYPEScatalogue is retained for when more types are productised. Hard-coded counts ("Twelve") removed.tests/api/routes/test_guardrails.py:test_list_validator_types_hides_non_exposed_typesmocks a 7-type upstream and asserts only the 4 come back, in order.docs/wiki/modules/guardrails.md: notes the filter and that only the list is filtered;POST/PATCH /guardrails/validators/configsstill forward any type.Verified against staging
Each of the 4 exposed types was exercised end to end on staging via
POST /guardrails/validators/configs+POST /guardrails(test configs deleted afterwards):uli_slur_match[REDACTED_SLUR]; English profanity and clean Hinglish untouched (verified locally throughbuild_guard; staging run usedcontent_safety, whose slur pass is the same validator)topic_relevance_llm(rephrase+fallback_message)gender_assumption_biasshe/his→they/theirpii_removerFAILEDwithInvalid on_fail value: fix— upstream bug, fixed in ProjectTech4DevAI/kaapi-guardrails#168 (not this PR)Checklist
uv run pytest app/tests/api/routes/test_guardrails.py→ 75 passed).Notes
🤖 Generated with Claude Code