mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
fix(guardrails): stop forwarding platform to the WonderFence V2 client constructor
The V2 SDK client signature is (api_key, base_url, *, api_timeout,
connection_pool_limit) and has no platform parameter, but client_cache
forwarded platform whenever it was configured. The shipped example_config sets
platform: "aws", so every scanning request raised TypeError
("unexpected keyword argument 'platform'"), surfaced as HTTP 500
guardrail_failed_to_respond with fail_open off. platform is a per-request
analysis attribute that already reaches the service via AnalysisContext
(build_analysis_context), so it is dropped from ClientBuildSpec and the client
kwargs; nothing is lost.
The existing test masked this because the SDK stub is a Mock that accepts any
kwargs, so it never exercised the real constructor signature. The client-cache
test now asserts platform is NOT forwarded to the client, paired with a new
processing test asserting build_analysis_context sets platform on the context.
Verified live against the shipped platform: "aws" config: a malicious prompt now
returns HTTP 400 BLOCK with real WonderFence detections instead of HTTP 500.
This commit is contained in:
parent
90ea9a7160
commit
1abc8e0720
4 changed files with 35 additions and 6 deletions
|
|
@ -188,7 +188,6 @@ class WonderFenceGuardrail(CustomGuardrail):
|
|||
client_class=self._WonderFenceV2Client,
|
||||
api_timeout=self.api_timeout,
|
||||
api_base=self.api_base,
|
||||
platform=self.platform,
|
||||
connection_pool_limit=self._connection_pool_limit,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,12 +12,19 @@ if TYPE_CHECKING:
|
|||
|
||||
@dataclass(frozen=True)
|
||||
class ClientBuildSpec:
|
||||
"""How to construct a WonderFenceV2Client on a cache miss."""
|
||||
"""How to construct a WonderFenceV2Client on a cache miss.
|
||||
|
||||
``platform`` is deliberately absent: it is a per-request analysis attribute
|
||||
that belongs on ``AnalysisContext`` (set by ``build_analysis_context``), not
|
||||
on the client constructor. The V2 client signature is
|
||||
``(api_key, base_url, *, api_timeout, connection_pool_limit)`` with no
|
||||
``platform`` parameter, so forwarding it here raised ``TypeError`` on every
|
||||
scan.
|
||||
"""
|
||||
|
||||
client_class: Callable[..., object]
|
||||
api_timeout: float
|
||||
api_base: str | None
|
||||
platform: str | None
|
||||
connection_pool_limit: int | None
|
||||
|
||||
|
||||
|
|
@ -58,8 +65,6 @@ def get_or_create_client(
|
|||
}
|
||||
if spec.api_base:
|
||||
client_kwargs["base_url"] = spec.api_base
|
||||
if spec.platform:
|
||||
client_kwargs["platform"] = spec.platform
|
||||
if spec.connection_pool_limit is not None:
|
||||
client_kwargs["connection_pool_limit"] = spec.connection_pool_limit
|
||||
|
||||
|
|
|
|||
|
|
@ -101,8 +101,13 @@ async def test_get_client_forwards_config_to_v2_client(install_sdk_stub):
|
|||
assert captured[0]["api_key"] == "resolved-key"
|
||||
assert captured[0]["base_url"] == "https://wf.example.com"
|
||||
assert captured[0]["api_timeout"] == 15 # rounded to int
|
||||
assert captured[0]["platform"] == "aws"
|
||||
assert captured[0]["connection_pool_limit"] == 42
|
||||
# ``platform`` must NOT be forwarded to the V2 client: its constructor is
|
||||
# (api_key, base_url, *, api_timeout, connection_pool_limit) and has no such
|
||||
# parameter, so forwarding it raised TypeError on every scan. platform is a
|
||||
# per-request analysis attribute that belongs on AnalysisContext instead
|
||||
# (see test_build_analysis_context_sets_platform_on_context).
|
||||
assert "platform" not in captured[0]
|
||||
|
||||
|
||||
# ----------------------------- initialization -----------------------------
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from litellm.proxy.guardrails.guardrail_hooks.alice_wonderfence.processing impor
|
|||
JOINER,
|
||||
RECONSTRUCT_MAX_CHARS,
|
||||
apply_response_verdicts,
|
||||
build_analysis_context,
|
||||
check_scan_budget,
|
||||
function_definition_segments,
|
||||
reconstruct,
|
||||
|
|
@ -20,6 +21,25 @@ from litellm.proxy.guardrails.guardrail_hooks.alice_wonderfence.processing impor
|
|||
)
|
||||
|
||||
|
||||
# --------------- build_analysis_context: platform belongs on the context ---------------
|
||||
|
||||
|
||||
def test_build_analysis_context_sets_platform_on_context():
|
||||
"""platform is a per-request analysis attribute and must be set on the
|
||||
AnalysisContext, NOT forwarded to the SDK client constructor (whose
|
||||
signature has no platform param). Pairs with
|
||||
test_get_client_forwards_config_to_v2_client asserting platform is not
|
||||
passed to the client."""
|
||||
captured: dict = {}
|
||||
|
||||
def context_class(**kwargs):
|
||||
captured.update(kwargs)
|
||||
return object()
|
||||
|
||||
build_analysis_context({"model": "gpt-4"}, "aws", context_class)
|
||||
assert captured["platform"] == "aws"
|
||||
|
||||
|
||||
def _block(detections=None, correlation_ids=None):
|
||||
return SegmentVerdict("BLOCK", None, detections or [], correlation_ids or [])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue