fix(protect): align metric names across Python and TypeScript SDKs - #56
Open
KarthikAvinashFI wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Python and TypeScript Protect SDKs exposed incompatible
metricnames for the same guardrail rules, so a rule config authored in one language was rejected by the other, and the docs had to document the two naming sets side by side with a warning that they do not mix. This aligns both SDKs on one canonical set ofsnake_casemetrics, keeps every historical name working as a back-compatible alias, and removesTone, which Protect does not support.This is the v1-refactor-branch version of the change (supersedes the
dev-based PR, whose file paths no longer exist on this branch).What changed
Both SDKs now accept the same superset: 4 canonical metrics plus every legacy alias, each resolving to the correct guardrail evaluation. Legacy names still work and emit a one-shot deprecation warning.
toxicitybias_detectionprompt_injectiondata_privacy_compliancecontent_moderationsecurityToxicitySexismPrompt InjectionData PrivacyToneFiles
src/fi/evals/protect.pymetric_mapextended with the TypeScript-origin legacy names;_deprecated_metricsextended so each alias emits aFutureWarningpointing at its canonical name; the data-privacy config is now selected by template identity (template_class is DataPrivacyCompliance) instead of a metric-name string comparison; the deadTonevalidation branch is removed; the fallback default rule and docstring example use canonicaltoxicityprotect()return shape, theaction/reasonvalidation, and the overall request flow are unchangedsrc/fi/evals/guardrails/backends/turing.pyclassify()uses canonicaltoxicity/prompt_injectionso it no longer emits a deprecation warning on every call; the category-lookup dict keeps the legacy keys so external callers still categorize correctlytypescript/agent-learning-kit/src/protect.tsmetric_maprewritten to the same canonical + legacy set; module-levelDEPRECATED_METRICSmap + one-shotconsole.warnper alias; data-privacy config selected by template identity;Toneand thevalidTypesset removed; the default rule uses canonicaltoxicityprotect()signature and result shape unchangedtests/test_protect_metric_map.pytypescript/agent-learning-kit/src/__tests__/protect.test.tsTonerejection; one pre-existing error-message assertion updated to the current messageBehavior callouts
data_privacy_compliancenow sendscheck_internet=false. The Python SDK previously selected this via a metric-name string that never matched its own map, so the flag was effectively never set; it is now selected by template identity and matches the TypeScript SDK. Data-privacy rules evaluate the input in isolation; a caller that relied on the old behaviour must opt in to internet lookups explicitly.Sexismnow resolves to the bias-detection evaluation. On the TypeScript sideSexismpreviously mapped to a separatesexistevaluation; it now maps tobias_detection(the canonical set), so existingSexismcallers run the bias-detection guardrail.FutureWarningin Python,console.warnin TypeScript). Removal is deferred to a future release.Toneis rejected. It was never a supported Protect metric; a rule using it now fails validation on both SDKs.Tests
tests/test_protect_metric_map.py(new)Tonerejectedtypescript/agent-learning-kit/src/__tests__/protect.test.ts(extended)TonerejectedBeyond the unit suites, every canonical and legacy metric name was exercised through
protect()end to end against a running Future AGI backend on both SDKs, confirming each is accepted, resolves to the correct guardrail evaluation, and round-trips successfully; legacy names emit their deprecation warning andToneis rejected.Commands
Output
Python unit:
TypeScript unit:
TypeScript typecheck: clean (
tsc --noEmit, no errors).End-to-end: every metric name sent through
protect()against a running backend (identical result on both SDKs):Scope in / scope out
In scope: metric-name alignment across both SDKs, back-compatible aliases with deprecation warnings,
Toneremoval, and the data-privacycheck_internetcorrection.Out of scope: widening the TypeScript
protect()input signature to acceptstring | listfor parity with Python. Deferred to keep this diff scoped; tracked separately.Design choices
Linear
Fix TH-7040