mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-12 15:19:16 +03:00
fix(tools): reject non-finite number parameters
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
"""Base class for agent tools."""
|
"""Base class for agent tools."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import math
|
||||||
import typing
|
import typing
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
@@ -67,6 +68,8 @@ class Schema(ABC):
|
|||||||
return [f"{label} should be number"]
|
return [f"{label} should be number"]
|
||||||
if t in _JSON_TYPE_MAP and t not in ("integer", "number") and not isinstance(val, _JSON_TYPE_MAP[t]):
|
if t in _JSON_TYPE_MAP and t not in ("integer", "number") and not isinstance(val, _JSON_TYPE_MAP[t]):
|
||||||
return [f"{label} should be {t}"]
|
return [f"{label} should be {t}"]
|
||||||
|
if t == "number" and isinstance(val, float) and not math.isfinite(val):
|
||||||
|
return [f"{label} must be finite"]
|
||||||
|
|
||||||
errors: list[str] = []
|
errors: list[str] = []
|
||||||
if "enum" in schema and val not in schema["enum"]:
|
if "enum" in schema and val not in schema["enum"]:
|
||||||
|
|||||||
@@ -598,6 +598,24 @@ def test_cast_params_invalid_string_to_number() -> None:
|
|||||||
assert result["rate"] == "not_a_number"
|
assert result["rate"] == "not_a_number"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value",
|
||||||
|
[float("nan"), float("inf"), float("-inf"), "NaN", "Infinity", "-Infinity"],
|
||||||
|
)
|
||||||
|
def test_cast_params_rejects_non_finite_numbers(value: float | str) -> None:
|
||||||
|
"""JSON number parameters must remain finite after schema-driven casting."""
|
||||||
|
tool = CastTestTool(
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"rate": {"type": "number"}},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = tool.cast_params({"rate": value})
|
||||||
|
|
||||||
|
assert tool.validate_params(result) == ["rate must be finite"]
|
||||||
|
|
||||||
|
|
||||||
def test_validate_params_bool_not_accepted_as_number() -> None:
|
def test_validate_params_bool_not_accepted_as_number() -> None:
|
||||||
"""Booleans should not pass number validation."""
|
"""Booleans should not pass number validation."""
|
||||||
tool = CastTestTool(
|
tool = CastTestTool(
|
||||||
|
|||||||
Reference in New Issue
Block a user