fix: suppress pydantic serializer warnings (#4291)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user