diff --git a/src/agents/run_internal/tool_execution.py b/src/agents/run_internal/tool_execution.py index af257b165f..71598cffc6 100644 --- a/src/agents/run_internal/tool_execution.py +++ b/src/agents/run_internal/tool_execution.py @@ -11,6 +11,7 @@ import functools import inspect import json +import math from collections.abc import Awaitable, Callable, Mapping, Sequence from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast @@ -694,7 +695,12 @@ def coerce_shell_call(tool_call: Any) -> ShellCallData: max_length_value = get_mapping_or_attr(action_payload, "max_output_length") if max_length_value is None: max_length_value = get_mapping_or_attr(action_payload, "maxOutputLength") - max_output_length = int(max_length_value) if isinstance(max_length_value, int | float) else None + if isinstance(max_length_value, int): + max_output_length = max_length_value + elif isinstance(max_length_value, float): + max_output_length = int(max_length_value) if math.isfinite(max_length_value) else 0 + else: + max_output_length = None action = ShellActionRequest( commands=commands, diff --git a/tests/test_shell_call_serialization.py b/tests/test_shell_call_serialization.py index 6737c99eef..b0afcd0c18 100644 --- a/tests/test_shell_call_serialization.py +++ b/tests/test_shell_call_serialization.py @@ -1,5 +1,7 @@ from __future__ import annotations +import math + import pytest from agents.agent import Agent @@ -23,6 +25,31 @@ def test_coerce_shell_call_reads_max_output_length() -> None: assert result.action.max_output_length == 512 +@pytest.mark.parametrize("max_output_length", [math.nan, math.inf, -math.inf]) +def test_coerce_shell_call_ignores_non_finite_max_output_length( + max_output_length: float, +) -> None: + tool_call = { + "call_id": "shell-non-finite-length", + "action": {"commands": ["ls"], "max_output_length": max_output_length}, + } + + result = run_loop.coerce_shell_call(tool_call) + + assert result.action.max_output_length == 0 + + +def test_coerce_shell_call_preserves_large_integer_max_output_length() -> None: + tool_call = { + "call_id": "shell-large-length", + "action": {"commands": ["ls"], "max_output_length": 10**400}, + } + + result = run_loop.coerce_shell_call(tool_call) + + assert result.action.max_output_length == 10**400 + + @pytest.mark.parametrize("timeout_key", ["timeout_ms", "timeoutMs", "timeout"]) @pytest.mark.parametrize("timeout_value", [0, 0.0]) def test_coerce_shell_call_treats_zero_timeout_as_unspecified(