fix: suppress pydantic serializer warnings (#4291)

This commit is contained in:
Kazuhiro Sera
2026-08-08 08:28:21 +09:00
committed by GitHub
parent 9c6cadf820
commit ae84ca1132
2 changed files with 70 additions and 2 deletions
+6 -1
View File
@@ -5,6 +5,8 @@ import json
from collections.abc import Mapping, Sequence
from typing import Any, TypeGuard
from pydantic import BaseModel
from ._tool_identity import (
FunctionToolLookupKey,
get_function_tool_lookup_key_for_call,
@@ -67,7 +69,10 @@ def _as_mapping(value: Any) -> Mapping[str, Any] | None:
return value
model_dump = getattr(value, "model_dump", None)
if callable(model_dump):
dumped = model_dump(exclude_none=True, exclude_unset=True)
kwargs = {"exclude_none": True, "exclude_unset": True}
if isinstance(value, BaseModel):
kwargs["warnings"] = False
dumped = model_dump(**kwargs)
return dumped if isinstance(dumped, Mapping) else None
return None
+64 -1
View File
@@ -2,6 +2,7 @@ from __future__ import annotations
import asyncio
import json
import warnings
from types import SimpleNamespace
from typing import Any, Literal, cast
@@ -12,6 +13,11 @@ from openai.types.responses.response_computer_tool_call import (
PendingSafetyCheck,
ResponseComputerToolCall,
)
from openai.types.responses.response_function_web_search import (
ActionSearch,
ActionSearchSource,
ResponseFunctionWebSearch,
)
from openai.types.responses.response_output_item import McpApprovalRequest
from openai.types.responses.response_reasoning_item import ResponseReasoningItem
@@ -33,7 +39,11 @@ from agents import (
handoff,
tool_output_guardrail,
)
from agents._tool_invocation import tool_invocation_identity, tool_invocation_identity_and_scope
from agents._tool_invocation import (
tool_invocation_call_id,
tool_invocation_identity,
tool_invocation_identity_and_scope,
)
from agents.editor import ApplyPatchOperation, ApplyPatchResult
from agents.exceptions import ModelBehaviorError, UserError
from agents.items import ModelResponse, ToolApprovalItem
@@ -79,6 +89,59 @@ def test_canonical_shell_identity_ignores_stripped_provider_metadata() -> None:
assert tool_invocation_identity(provider_call) == tool_invocation_identity(persisted_call)
def test_web_search_source_schema_drift_does_not_warn_during_invocation_lookup() -> None:
source = ActionSearchSource.model_construct(type="api", name="oai-calculator")
output_item = ResponseFunctionWebSearch(
id="ws_123",
action=ActionSearch(type="search", query="current market data", sources=[source]),
status="completed",
type="web_search_call",
)
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always", UserWarning)
call_id = tool_invocation_call_id(output_item)
serializer_warnings = [
warning
for warning in caught_warnings
if "Pydantic serializer warnings" in str(warning.message)
]
assert call_id is None
assert not serializer_warnings
def test_invocation_lookup_preserves_legacy_model_dump_signature() -> None:
class LegacyModel:
def model_dump(self, *, exclude_none: bool, exclude_unset: bool) -> dict[str, str]:
assert exclude_none is True
assert exclude_unset is True
return {"type": "function_call", "call_id": "call_legacy"}
assert tool_invocation_call_id(LegacyModel()) == ("function_call", "call_legacy")
def test_invocation_lookup_propagates_internal_model_dump_type_error() -> None:
class FailingModel:
def __init__(self) -> None:
self.calls = 0
def model_dump(
self,
*,
exclude_none: bool,
exclude_unset: bool,
warnings: bool = True,
) -> dict[str, str]:
self.calls += 1
raise TypeError("internal serialization failure")
model = FailingModel()
with pytest.raises(TypeError, match="internal serialization failure"):
tool_invocation_call_id(model)
assert model.calls == 1
def test_canonical_shell_identity_treats_optional_nulls_as_omitted() -> None:
provider_call = {
"type": "shell_call",