Skip to content

feat(guardrails): Filter validator types response - #1257

Merged
AkhileshNegi merged 11 commits into
mainfrom
enhancement/guardrail-list-api
Oct 15, 2026
Merged

AkhileshNegi merged 11 commits into
mainfrom
enhancement/guardrail-list-api

Conversation

@AkhileshNegi

@AkhileshNegi AkhileshNegi commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Issue

Closes #1256

Summary

  • Before: GET /api/v1/guardrails returned a full list of 12 validator types.
  • Now: The endpoint filters the response to expose only four specific validator types for the Glific guardrails v1.0 integration.
  • Implemented a filtering mechanism to limit the returned validator types.
  • Updated OpenAPI documentation to reflect the changes in the response.

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran fastapi run --reload app/main.py or docker compose up in the repository root and test.
  • If you've fixed a bug or added code that is tested and has test cases.

Notes

  • Scope changed mid-review: v1.0 wants slur redaction only, so uli_slur_match replaced content_safety (whose profanity pass blanks the whole message).
  • Only the list is filtered. Non-exposed types can still be saved via the config endpoints; rejecting them there is a possible follow-up.
  • The response still carries no display metadata (labels, descriptions, languages, accuracy). The Glific PRD needs those; separate follow-up.

Manual test: minimum inline config per validator

Send to kaapi-guardrails POST / (Bearer auth + X-ORGANIZATION-ID / X-PROJECT-ID). type is the only required key; everything else has a default. on_fail_action is accepted as an alias for on_fail.

Validator Minimum config Defaults you get
Privacy Protection {"type": "pii_remover"} on_fail: fix, 12 pattern-based entity_types
Slur Match {"type": "uli_slur_match"} on_fail: fix, severity: all, languages: ["en", "hi"]
Scope Control {"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. rephrase is required for the fallback to be used; with fix a blocked message becomes ""
Gender Neutrality {"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:

Validator Input Expected output
pii_remover My name is Rahul Sharma from Pune, call 9876543210 or email [email protected]. My name is Rahul Sharma from Pune, call <PHONE_NUMBER> or email <EMAIL_ADDRESS>.
pii_remover + "entity_types": ["PERSON", "LOCATION", "PHONE_NUMBER", "EMAIL_ADDRESS"] same My name is <PERSON> from <LOCATION>, call <PHONE_NUMBER> or email <EMAIL_ADDRESS>.
uli_slur_match Tu bhenchod hai, bank balance kaise check karu? tu [REDACTED_SLUR] hai, bank balance kaise check karu?
uli_slur_match This is fucking bullshit, what the hell is wrong with this app unchanged (English profanity is not in the slur list; no profanity pass)
uli_slur_match + "severity": "high" Kutta kahin ka, loan status batao unchanged (kutta is severity L; default all redacts it)
uli_slur_match Kaise ho? Meri fasal me keede lag gaye hain. unchanged
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? unchanged
gender_assumption_bias The 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/guardrails returned 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_TYPES frozenset + 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_types applies the filter before _upstream_response.
  • api/docs/guardrails_schemas.py: _ordered_types() and render_validator_reference() render only exposed types, so the Swagger example and the per-type reference match the response. Full VALIDATOR_TYPES catalogue 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_types mocks 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/configs still 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):

Validator Result
uli_slur_match slur → [REDACTED_SLUR]; English profanity and clean Hinglish untouched (verified locally through build_guard; staging run used content_safety, whose slur pass is the same validator)
topic_relevance_llm (rephrase + fallback_message) off-topic EN → fallback; off-topic HI → fallback translated to Hindi; on-topic untouched
gender_assumption_bias she/his → they/their
pii_remover job FAILED with Invalid on_fail value: fix — upstream bug, fixed in ProjectTech4DevAI/kaapi-guardrails#168 (not this PR)

Checklist

  • Ran the server and tested the endpoint against staging.
  • Added a test case for the filter (uv run pytest app/tests/api/routes/test_guardrails.py → 75 passed).

Notes

  • Only the list is filtered. Non-exposed types can still be saved via the config endpoints; rejecting them there is a possible follow-up.
  • The response still carries no display metadata (labels, descriptions, languages, accuracy). The Glific PRD needs those; separate follow-up.

🤖 Generated with Claude Code

Prajna1999 and others added 6 commits September 30, 2026 15:57
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) <[email protected]>
…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 <[email protected]>
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one): 1
  • ready-for-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: ProjectTech4DevAI/kaapi-backend/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c75810e0-de07-44f5-b8dc-bcf74512703e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot changed the title feat(guardrails): expose only the v1.0 validator types on GET /guardrails feat(guardrails): Filter validator types response Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

OpenAPI changes   ⚪ No API surface changes

Note

This PR does not modify the API contract.

main ↔ 260b9e99 · generated by oasdiff

@AkhileshNegi AkhileshNegi self-assigned this Oct 15, 2026
@AkhileshNegi AkhileshNegi added the enhancement New feature or request label Oct 15, 2026
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.45455% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
backend/app/api/docs/guardrails_schemas.py 83.33% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

AkhileshNegi and others added 2 commits October 15, 2026 13:32
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 <[email protected]>
@AkhileshNegi
AkhileshNegi enabled auto-merge (squash) October 15, 2026 08:09
@AkhileshNegi
AkhileshNegi merged commit bf0eca6 into main Oct 15, 2026
6 checks passed
@AkhileshNegi
AkhileshNegi deleted the enhancement/guardrail-list-api branch October 15, 2026 08:23
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.8.0-main.11 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request released on @main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Guardrails: Filter validator API

2 participants