Repository navigation
feat(guardrails): add decision model guardrail with Admin UI flow #45663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 48 commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
c830164
feat(guardrails): add decision_model guardrail for decisions-API models
yucheng-berri 14bd1c0
fix(guardrails): fail closed on verdict errors and drop comments in d…
devin-ai-integration[bot] 555383e
feat(guardrails): cap decision_model input with head and tail elision
devin-ai-integration[bot] eba1d0c
fix(guardrails): list only block checks in decision_model 400s and ti…
devin-ai-integration[bot] d29e514
feat(guardrails): honor timeout, cap checks at MAX_DECISION_QUESTIONS…
devin-ai-integration[bot] 37ba091
fix(guardrails): decorate decision_model apply_guardrail with log_gua…
devin-ai-integration[bot] 7be7341
fix(guardrails): suppress untyped-decorator pyright error on log_guar…
devin-ai-integration[bot] b19ce71
feat(guardrails): screen each text in overlapping chunks with a share…
devin-ai-integration[bot] f055f90
fix(ui): align decision model custom check rows with preset rows
devin-ai-integration[bot] 12ecc9a
fix(ui): move decision model custom check remove button to the row end
devin-ai-integration[bot] 880d0ce
style(ui): run prettier on decision model check files
devin-ai-integration[bot] 0c6d969
fix(ui): inline decision model evaluation-mode filter after lens modu…
devin-ai-integration[bot] a17eaeb
fix(guardrails): keep decision model detections when a chunk call fails
devin-ai-integration[bot] a143df6
fix(ui): require an enabled decision model check before create
devin-ai-integration[bot] 242e655
fix(guardrails): screen decision model texts sequentially like presidio
devin-ai-integration[bot] 4afc7c8
feat(guardrails): replace decision model presets with provider picker…
devin-ai-integration[bot] 2939874
fix(ui): render decision model question test as a full-width row
devin-ai-integration[bot] 4e46072
feat(ui): add run-history test section to decision model form
devin-ai-integration[bot] 2f12fe1
fix(ui): prevent threshold overlap and show test shortcut
devin-ai-integration[bot] d6371b6
feat(guardrails): default decision model threshold to 0.7
devin-ai-integration[bot] f75011d
test(ui): expect decision model default threshold 0.7 in characteriza…
devin-ai-integration[bot] d3feaad
Merge remote-tracking branch 'origin/main' into litellm_decision_mode…
devin-ai-integration[bot] 1d2b892
feat(guardrails): screen tool call arguments with the decision model
devin-ai-integration[bot] fcc91b1
refactor(guardrails): freeze the decision model config model
devin-ai-integration[bot] e0ff45b
feat(guardrails): list only evaluation-mode deployments in the decisi…
devin-ai-integration[bot] a6021ea
feat(guardrails): hide the decision model questions table until a que…
devin-ai-integration[bot] 6bb1b6d
style(ui): format DecisionModelFields
devin-ai-integration[bot] 529da92
style(ui): format decisionModelQuestion tests
devin-ai-integration[bot] a2e5a3b
refactor(guardrails): type the tool call function extraction
devin-ai-integration[bot] fdf7d25
refactor(guardrails): build tool call texts without a mutable accumul…
devin-ai-integration[bot] 6bac6fb
refactor(ui): share isDecisionMode for the decision model picker
devin-ai-integration[bot] 20592fd
fix(guardrails): screen prior Responses function call arguments in th…
yucheng-berri 4cc5b57
test(integration): send instructions with the decision model guardrai…
yucheng-berri be9a6dc
fix(ui): score the decision model test preview the way the guardrail …
yucheng-berri f9ed58c
fix(ui): clear the decision model error on pick and list questions un…
yucheng-berri f75d92a
test(ui): move the decision model form tests into an integration test…
yucheng-berri d053284
test(guardrails): build the decision model test params without mutati…
yucheng-berri ba5bf63
Merge remote-tracking branch 'origin/main' into litellm_decision_mode…
yucheng-berri 8923e11
fix(guardrails): reject list checks outside decision_model and honor …
yucheng-berri 7fa49a1
fix(ui): match guardrail providers like the default picker filter
yucheng-berri c8a5826
fix(ui): edit decision model questions in place and show passing test…
yucheng-berri 9795188
fix(ui): drop the per-question enable checkbox from the decision mode…
yucheng-berri 4422fca
fix(ui): give the question name field the full card width
yucheng-berri 5802e35
fix(ui): show the provider logo on the selected decision provider
yucheng-berri 22f7fc9
fix(ui): show the full threshold slider track on decision model quest…
yucheng-berri 549c824
feat(ui): add decision model cards to the guardrail garden
yucheng-berri 335d853
fix(ui): shorten the decision model test hint to one line
yucheng-berri 8787e69
fix(ui): prefill the decision model from the garden card's provider
yucheng-berri 56950ff
Merge commit '000b3685ed06e8d5f9a7e1cd6bdf00bc5f59771e' into pr45663-…
yucheng-berri 6f80b29
chore(ui): regenerate the dashboard API types after merging main
yucheng-berri be36290
Merge branch 'main' of https://github.com/BerriAI/litellm into pr4566…
yucheng-berri File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
109 changes: 109 additions & 0 deletions
109
litellm/proxy/guardrails/guardrail_hooks/decision_model/__init__.py
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from collections.abc import Sequence | ||
| from typing import TYPE_CHECKING, Final | ||
|
|
||
| from pydantic import TypeAdapter, ValidationError | ||
|
|
||
| from litellm.types.guardrails import ( | ||
| GuardrailEventHooks, | ||
| Mode, | ||
| SupportedGuardrailIntegrations, | ||
| ) | ||
| from litellm.types.proxy.guardrails.guardrail_hooks.decision_model import ( | ||
| DecisionModelCheck, | ||
| ) | ||
|
|
||
| from .decision_model import DecisionModelGuardrail | ||
|
|
||
| if TYPE_CHECKING: | ||
| from litellm.types.guardrails import Guardrail, LitellmParams | ||
|
|
||
| _CHECKS_ADAPTER: Final = TypeAdapter(list[DecisionModelCheck]) | ||
|
|
||
|
|
||
| def _coerce_event_hook( | ||
| mode: str | Sequence[str] | Mode, | ||
| ) -> GuardrailEventHooks | tuple[GuardrailEventHooks, ...] | Mode: | ||
| if isinstance(mode, Mode): | ||
| return mode | ||
| if isinstance(mode, str): | ||
| return GuardrailEventHooks(mode) | ||
| return tuple(GuardrailEventHooks(item) for item in mode) | ||
|
|
||
|
|
||
| def _parse_checks(raw_checks: object) -> tuple[DecisionModelCheck, ...]: | ||
| try: | ||
| checks: Final = _CHECKS_ADAPTER.validate_python(raw_checks) | ||
| except ValidationError as error: | ||
| raise ValueError(f"decision_model guardrail has invalid checks: {error}") from error | ||
| return tuple(checks) | ||
|
|
||
|
|
||
| def _streaming_end_of_stream_only(litellm_params: LitellmParams) -> bool: | ||
| value: Final[object] = getattr(litellm_params, "streaming_end_of_stream_only", None) | ||
| if value is None: | ||
| return False | ||
| if not isinstance(value, bool): | ||
| raise TypeError(f"decision_model guardrail streaming_end_of_stream_only must be a boolean, got {value!r}") | ||
| return value | ||
|
|
||
|
|
||
| def _streaming_sampling_rate(litellm_params: LitellmParams) -> int: | ||
| value: Final[object] = getattr(litellm_params, "streaming_sampling_rate", None) | ||
| if value is None: | ||
| return 5 | ||
| if isinstance(value, bool) or not isinstance(value, int): | ||
| raise TypeError(f"decision_model guardrail streaming_sampling_rate must be an integer, got {value!r}") | ||
| if value < 1: | ||
| raise ValueError(f"decision_model guardrail streaming_sampling_rate must be at least 1, got {value}") | ||
| return value | ||
|
|
||
|
|
||
| def initialize_guardrail(litellm_params: LitellmParams, guardrail: Guardrail) -> DecisionModelGuardrail: | ||
| import litellm | ||
|
|
||
| decision_model: Final = litellm_params.decision_model | ||
| if not decision_model: | ||
| raise ValueError("decision_model guardrail requires decision_model in litellm_params") | ||
|
|
||
| checks: Final = _parse_checks(litellm_params.checks) | ||
|
|
||
| _callback: Final = DecisionModelGuardrail( | ||
| guardrail_name=guardrail["guardrail_name"], | ||
| decision_model=decision_model, | ||
| checks=checks, | ||
| event_hook=_coerce_event_hook(litellm_params.mode), | ||
| default_on=litellm_params.default_on or False, | ||
| unreachable_fallback=( | ||
| litellm_params.unreachable_fallback | ||
| if "unreachable_fallback" in litellm_params.model_fields_set | ||
| else "fail_closed" | ||
| ), | ||
| max_input_chars=litellm_params.max_input_chars or 24000, | ||
| timeout=litellm_params.timeout, | ||
| max_concurrent_decision_calls=litellm_params.max_concurrent_decision_calls or 8, | ||
| streaming_end_of_stream_only=_streaming_end_of_stream_only(litellm_params), | ||
| streaming_sampling_rate=_streaming_sampling_rate(litellm_params), | ||
| ) | ||
| litellm.logging_callback_manager.add_litellm_callback( # pyright: ignore[reportUnknownMemberType] # callback manager is untyped | ||
| _callback | ||
| ) | ||
| return _callback | ||
|
|
||
|
|
||
| guardrail_initializer_registry: Final = { | ||
| SupportedGuardrailIntegrations.DECISION_MODEL.value: initialize_guardrail, | ||
| } | ||
|
|
||
| guardrail_class_registry: Final = { | ||
| SupportedGuardrailIntegrations.DECISION_MODEL.value: DecisionModelGuardrail, | ||
| } | ||
|
|
||
|
|
||
| __all__ = [ | ||
| "DecisionModelGuardrail", | ||
| "guardrail_class_registry", | ||
| "guardrail_initializer_registry", | ||
| "initialize_guardrail", | ||
| ] | ||
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.