Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/agents/run_internal/tool_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand Down
27 changes: 27 additions & 0 deletions tests/test_shell_call_serialization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import math

import pytest

from agents.agent import Agent
Expand All @@ -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(
Expand Down