fix(types): make the changed DynamoAI fields ReadOnly and skip non-object A2A stream items

This commit is contained in:
mateo-berri 2026-10-28 18:12:21 -07:00
parent 2ddd7a34e3
commit ae17009b02
3 changed files with 11 additions and 6 deletions

View file

@ -14,7 +14,7 @@ import json
from collections.abc import Sequence
from typing import TYPE_CHECKING, Any, Final, Optional
from pydantic import ConfigDict, TypeAdapter
from pydantic import ConfigDict, TypeAdapter, ValidationError
from typing_extensions import ReadOnly, TypedDict
from litellm._logging import verbose_proxy_logger
@ -337,7 +337,7 @@ class A2AGuardrailHandler(BaseTranslation):
elif isinstance(item, str):
try:
obj = _JSON_OBJECT.validate_python(json.loads(item.strip()))
except (json.JSONDecodeError, TypeError):
except (json.JSONDecodeError, TypeError, ValidationError):
continue
else:
continue

View file

@ -5,6 +5,7 @@ from collections.abc import Mapping
from typing import Literal, TypedDict
from pydantic import Field
from typing_extensions import ReadOnly
from .base import GuardrailConfigModel
@ -42,7 +43,7 @@ class PolicyApplicableTo(str, enum.Enum):
class DynamoAIRequest(TypedDict, total=False):
"""Request structure for DynamoAI /moderation/analyze endpoint"""
messages: list[dict[str, object]]
messages: ReadOnly[list[dict[str, object]]]
textType: DynamoTextType | None
policyIds: list[str]
modelId: str | None
@ -58,8 +59,8 @@ class PolicyInfo(TypedDict, total=False):
description: str
method: PolicyMethod
action: Literal["BLOCK", "WARN", "REDACT", "SANITIZE", "NONE"]
methodParams: dict[str, object]
decisionParams: dict[str, object]
methodParams: ReadOnly[dict[str, object]]
decisionParams: ReadOnly[dict[str, object]]
applicableTo: PolicyApplicableTo
created_at: str
creatorId: str
@ -76,7 +77,7 @@ class AppliedPolicyDto(TypedDict, total=False):
"""Applied policy details from DynamoAI response"""
policy: PolicyInfo
outputs: dict[str, object] | None
outputs: ReadOnly[dict[str, object] | None]
action: str | None

View file

@ -33,3 +33,7 @@ class TestA2AGuardrailHandlerStreamingScanKey:
def test_unparseable_items_are_ignored(self):
key = A2AGuardrailHandler().get_streaming_scan_key([_text_event("hi"), "not json", b"bytes"])
assert key.texts == ("hi",)
def test_json_items_that_are_not_objects_are_ignored(self):
key = A2AGuardrailHandler().get_streaming_scan_key([_text_event("hi"), "[1, 2]", "5"])
assert key.texts == ("hi",)