mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 13:16:24 +00:00
fix(tencent_wsa): fall back when digit-class max_results cannot parse (#6973)
* fix(tencent_wsa): fall back when digit-class max_results cannot parse str.isdigit() accepts values like "²" and "1²" that int() rejects, so a configured max_results could crash web_search_tool before the HTTP call. Parse strings with int() inside try/except (matching sibling providers) while still rejecting bools and non-integral floats. Fixes #6921 * docs(tencent_wsa): clarify that all float max_results fall back to default
This commit is contained in:
parent
75de35628d
commit
453563af5b
@ -41,10 +41,26 @@ def _get_api_key(tool_name: str = "web_search", *, extras: Mapping[str, Any] | N
|
||||
|
||||
|
||||
def _coerce_max_results(value: object, *, default: int = _DEFAULT_MAX_RESULTS) -> int:
|
||||
if isinstance(value, int) and not isinstance(value, bool):
|
||||
"""Coerce configured/tool max_results into a bounded positive int.
|
||||
|
||||
Bools and all floats (including integral ones such as 2.0) fall back to
|
||||
the default; only ints and integer strings are accepted.
|
||||
String parsing uses ``int(...)`` inside a try/except so digit-class Unicode
|
||||
that ``str.isdigit()`` accepts but ``int`` rejects (e.g. ``"²"``, ``"1²"``)
|
||||
falls back to the default instead of raising, matching Brave/Serply/etc.
|
||||
Valid decimal Unicode such as ``"٣"`` still parses.
|
||||
"""
|
||||
if isinstance(value, bool):
|
||||
logger.warning("Invalid Tencent Cloud WSA max_results=%r; using default %s", value, default)
|
||||
return default
|
||||
if isinstance(value, int):
|
||||
result = value
|
||||
elif isinstance(value, str) and value.strip().isdigit():
|
||||
result = int(value.strip())
|
||||
elif isinstance(value, str):
|
||||
try:
|
||||
result = int(value.strip())
|
||||
except (ValueError, OverflowError):
|
||||
logger.warning("Invalid Tencent Cloud WSA max_results=%r; using default %s", value, default)
|
||||
return default
|
||||
else:
|
||||
logger.warning("Invalid Tencent Cloud WSA max_results=%r; using default %s", value, default)
|
||||
return default
|
||||
|
||||
@ -331,13 +331,56 @@ class TestTencentWsaSearch:
|
||||
class TestTencentWsaConfiguration:
|
||||
@pytest.mark.parametrize(
|
||||
("value", "expected"),
|
||||
[(3, 3), ("7", 7), (True, 5), (2.9, 5), (0, 5), (-1, 5), (500, 50), ("bad", 5)],
|
||||
[
|
||||
(3, 3),
|
||||
("7", 7),
|
||||
(True, 5),
|
||||
(2.9, 5),
|
||||
(0, 5),
|
||||
(-1, 5),
|
||||
(500, 50),
|
||||
("bad", 5),
|
||||
# str.isdigit() is true for these, but int() raises ValueError (#6921).
|
||||
("²", 5),
|
||||
("1²", 5),
|
||||
# Valid non-ASCII decimal digits must still parse.
|
||||
("٣", 3),
|
||||
],
|
||||
)
|
||||
def test_coerce_max_results(self, value, expected):
|
||||
from deerflow.community.tencent_wsa.tools import _coerce_max_results
|
||||
|
||||
assert _coerce_max_results(value) == expected
|
||||
|
||||
def test_configured_unparseable_digit_max_results_falls_back(self):
|
||||
"""Config max_results that passes isdigit but fails int must not crash invoke."""
|
||||
page = json.dumps(
|
||||
{
|
||||
"title": "ok",
|
||||
"url": "https://example.com",
|
||||
"content": "snippet",
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
http_response = MagicMock()
|
||||
http_response.json.return_value = _response([page])
|
||||
_client, context_manager = _mock_http_client(http_response)
|
||||
|
||||
with (
|
||||
patch("deerflow.community.tencent_wsa.tools.get_app_config") as get_config,
|
||||
patch("deerflow.community.tencent_wsa.tools.httpx.Client", return_value=context_manager),
|
||||
):
|
||||
get_config.return_value.get_tool_config.return_value = _tool_config({"api_key": "test-key", "max_results": "²"})
|
||||
|
||||
from deerflow.community.tencent_wsa.tools import web_search_tool
|
||||
|
||||
result = json.loads(web_search_tool.run({"query": "腾讯云"}))
|
||||
|
||||
assert "error" not in result
|
||||
assert result["query"] == "腾讯云"
|
||||
assert result["total_results"] == 1
|
||||
assert result["results"][0]["title"] == "ok"
|
||||
|
||||
@pytest.mark.parametrize("value", (None, "2", True, 2.0, "bad", -1, 3))
|
||||
def test_invalid_mode_is_omitted(self, value):
|
||||
with patch("deerflow.community.tencent_wsa.tools.get_app_config") as get_config:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user