Skip to content

Commit 09f0ed4

Browse files
authored
fix: enforce the documented strict JSON-compatible contract for #3486 (#3657)
1 parent 7fc489e commit 09f0ed4

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

src/agents/util/_custom_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def normalize_custom_data(value: Mapping[str, Any] | None) -> dict[str, Any] | N
2828

2929
copied = copy.deepcopy(dict(value))
3030
try:
31-
return cast(dict[str, Any], json.loads(json.dumps(copied)))
31+
return cast(dict[str, Any], json.loads(json.dumps(copied, allow_nan=False)))
3232
except (TypeError, ValueError) as exc:
3333
raise UserError("custom_data_extractor must return JSON-compatible data.") from exc
3434

tests/test_tool_custom_data.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,25 @@ def get_data() -> str:
9696
await Runner.run(agent, input="user")
9797

9898

99+
@pytest.mark.asyncio
100+
@pytest.mark.parametrize("bad_value", [float("nan"), float("inf"), float("-inf")])
101+
async def test_function_tool_custom_data_rejects_non_finite_floats(
102+
bad_value: float,
103+
) -> None:
104+
@function_tool(custom_data_extractor=lambda _ctx: {"score": bad_value})
105+
def get_data() -> str:
106+
return "tool_result"
107+
108+
model = FakeModel()
109+
model.add_multiple_turn_outputs(
110+
[[get_text_message("call tool"), get_function_tool_call("get_data", "{}")]]
111+
)
112+
agent = Agent(name="test", model=model, tools=[get_data])
113+
114+
with pytest.raises(UserError, match="custom_data_extractor must return JSON-compatible data"):
115+
await Runner.run(agent, input="user")
116+
117+
99118
@pytest.mark.asyncio
100119
async def test_mcp_custom_data_extractor_maps_result_meta_to_tool_output_item() -> None:
101120
def extract_custom_data(ctx: Any) -> dict[str, Any]:

0 commit comments

Comments
 (0)