mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-02 02:11:58 +00:00
fix(guardrails): default a scheme-less Agent 365 authority host to https and treat a null fallback as unset in the YAML preview
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
172b128178
commit
96d79c9135
5 changed files with 29 additions and 4 deletions
|
|
@ -178,7 +178,8 @@ class Agent365Guardrail(CustomGuardrail):
|
|||
self.api_base = api_base.rstrip("/")
|
||||
self.resource_app_id = resource_app_id
|
||||
self.agent_id = agent_id
|
||||
self.authority_host = authority_host.rstrip("/")
|
||||
authority: Final = authority_host.strip().rstrip("/")
|
||||
self.authority_host = authority if "://" in authority else f"https://{authority}"
|
||||
self.request_timeout = request_timeout
|
||||
self.unreachable_fallback: Literal["fail_closed", "fail_open"] = (
|
||||
"fail_closed" if unreachable_fallback == "fail_closed" else "fail_open"
|
||||
|
|
|
|||
|
|
@ -307,6 +307,14 @@ class TestInitializeGuardrail:
|
|||
)
|
||||
assert explicit.authority_host == "http://127.0.0.1:9"
|
||||
|
||||
def test_scheme_less_authority_host_env_gets_https(self, monkeypatch):
|
||||
monkeypatch.setenv("AZURE_AUTHORITY_HOST", " login.microsoftonline.us/ ")
|
||||
guardrail: Final = initialize_guardrail(
|
||||
LitellmParams(guardrail="agent_365", mode="pre_mcp_call", tenant_id="t", client_id="c", client_secret="s"),
|
||||
{"guardrail_name": "a365-bare-host"},
|
||||
)
|
||||
assert guardrail.authority_host == "https://login.microsoftonline.us"
|
||||
|
||||
def test_explicit_params_win(self, monkeypatch):
|
||||
monkeypatch.setenv("AGENT365_TENANT_ID", "env-tenant")
|
||||
params: Final = LitellmParams(
|
||||
|
|
@ -381,6 +389,13 @@ class TestAllowFlow:
|
|||
assert handler.calls[0].url == "https://login.microsoftonline.us/tenant-abc/oauth2/v2.0/token"
|
||||
assert handler.calls[1].url == EVALUATE_URL
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_obo_exchange_adds_https_to_a_bare_authority_host(self):
|
||||
handler: Final = FakeHandler([_token_response(), _allow_response()])
|
||||
guardrail: Final = _make_guardrail(handler, authority_host="login.microsoftonline.us")
|
||||
await _run(guardrail, _mcp_data())
|
||||
assert handler.calls[0].url == "https://login.microsoftonline.us/tenant-abc/oauth2/v2.0/token"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_payload(self):
|
||||
handler: Final = FakeHandler([_token_response(), _allow_response()])
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ function submissionToTeamGuardrail(item: GuardrailSubmissionItem): TeamGuardrail
|
|||
submittedAt: formatSubmissionDate(item.submitted_at),
|
||||
submittedBy: item.submitted_by_email ?? item.submitted_by_user_id ?? "—",
|
||||
mode: params.mode as string | undefined,
|
||||
unreachable_fallback: params.unreachable_fallback as string | undefined,
|
||||
unreachable_fallback: params.unreachable_fallback as string | null | undefined,
|
||||
additionalProviderParams: params.additional_provider_specific_params as Record<string, unknown> | undefined,
|
||||
guardrailType: params.guardrail as string | undefined,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ describe("buildEquivalentConfigYaml unreachable_fallback line", () => {
|
|||
expect(untyped).toContain(" guardrail: generic_guardrail_api");
|
||||
});
|
||||
|
||||
it("treats a null fallback from the API as unset and shows the per-guardrail default", () => {
|
||||
expect(
|
||||
fallbackLine(buildEquivalentConfigYaml(guardrail({ guardrailType: "agent_365", unreachable_fallback: null }))),
|
||||
).toBe("unreachable_fallback: fail_open");
|
||||
expect(
|
||||
fallbackLine(buildEquivalentConfigYaml(guardrail({ guardrailType: "akto", unreachable_fallback: null }))),
|
||||
).toBe("unreachable_fallback: fail_closed");
|
||||
});
|
||||
|
||||
it("keeps an explicit override over the per-guardrail default", () => {
|
||||
expect(
|
||||
fallbackLine(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export type TeamGuardrail = {
|
|||
submittedAt: string;
|
||||
submittedBy: string;
|
||||
mode?: string;
|
||||
unreachable_fallback?: string;
|
||||
unreachable_fallback?: string | null;
|
||||
additionalProviderParams?: Record<string, unknown>;
|
||||
guardrailType?: string;
|
||||
};
|
||||
|
|
@ -33,7 +33,7 @@ export function defaultUnreachableFallback(guardrailType: string | undefined): "
|
|||
|
||||
function unreachableFallbackLine(g: TeamGuardrail): string {
|
||||
const hint = "fail_closed blocks, fail_open proceeds when the guardrail endpoint is unreachable";
|
||||
if (g.unreachable_fallback !== undefined) {
|
||||
if (g.unreachable_fallback) {
|
||||
return ` unreachable_fallback: ${g.unreachable_fallback} # ${hint}`;
|
||||
}
|
||||
return ` unreachable_fallback: ${defaultUnreachableFallback(g.guardrailType)} # ${hint}. Shown value is this guardrail's default.`;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue