[Bugfix] Accept whole-number floats for integer tool arguments in the response parser (#61297)

Signed-off-by: Yoni Gozlan <74535834+yonigozlan@users.noreply.github.com>
Signed-off-by: Bugen Zhao <i@bugenzhao.com>
Co-authored-by: Bugen Zhao <i@bugenzhao.com>
This commit is contained in:
Yoni Gozlan
2026-10-13 12:55:20 +08:00
committed by GitHub
co-authored by Bugen Zhao
parent 28d679e762
commit 69d00bc264
2 changed files with 16 additions and 1 deletions
+8
View File
@@ -1555,6 +1555,14 @@ class ToolArgCoercionTest(unittest.TestCase):
def test_coerce_falls_back_to_raw_on_failure(self):
self.assertEqual(_coerce("not-a-number", ("integer",)), "not-a-number")
def test_coerce_integer_accepts_whole_number_floats(self):
self.assertEqual(_coerce("3.0", ("integer",)), 3)
self.assertIsInstance(_coerce("3.0", ("integer",)), int)
self.assertEqual(_coerce("3.5", ("integer",)), "3.5")
self.assertEqual(_coerce("3.5", ("integer", "number")), 3.5)
self.assertEqual(_coerce("inf", ("integer",)), "inf")
self.assertEqual(_coerce("NaN", ("integer",)), "NaN")
def test_coerce_handles_any_of_and_null(self):
self.assertEqual(_coerce("5", ("integer", "null")), 5)
self.assertIsNone(_coerce("null", ("integer", "null")))
+8 -1
View File
@@ -50,7 +50,14 @@ def _coerce(raw: str, types: tuple[str, ...]) -> Any:
for type_name in types:
try:
if type_name == "integer":
return int(raw)
try:
return int(raw)
except ValueError:
# JSON Schema integers include whole numbers written as floats, e.g. "3.0"
number = float(raw)
if not number.is_integer():
continue
return int(number)
if type_name == "number":
number = float(raw)
if number != number or number in (float("inf"), float("-inf")):