mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-12 14:00:35 +00:00
* fix(serply): delegate max_results coercion to shared owner (#7869) * refactor(serply): simplify count helper and consolidate tests --------- Co-authored-by: AochenShen99 <sac1063467113@hotmail.com>
This commit is contained in:
parent
bfa2794c76
commit
10bbcc92de
@ -17,6 +17,7 @@ import re
|
||||
import httpx
|
||||
from langchain.tools import tool
|
||||
|
||||
from deerflow.community.search_max_results import coerce_max_results
|
||||
from deerflow.community.url_safety import safe_public_result_url
|
||||
from deerflow.config import get_app_config
|
||||
|
||||
@ -51,21 +52,18 @@ def _get_api_key(tool_name: str = "web_search") -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def _coerce_max_results(
|
||||
value: object,
|
||||
*,
|
||||
default: int = _DEFAULT_MAX_RESULTS,
|
||||
max_allowed: int = _SERPLY_MAX_RESULTS,
|
||||
) -> int:
|
||||
try:
|
||||
coerced = int(value)
|
||||
except (TypeError, ValueError, OverflowError):
|
||||
logger.warning("Invalid Serply max_results=%r; using default %s", value, default)
|
||||
coerced = default
|
||||
if coerced < 1:
|
||||
logger.warning("Invalid Serply max_results=%r; using default %s", value, default)
|
||||
coerced = default
|
||||
return min(coerced, max_allowed)
|
||||
def _count_for_request(value: object) -> int:
|
||||
"""Coerce ``max_results`` via the shared owner, then mirror Serply's clamp.
|
||||
|
||||
``deerflow.community.search_max_results.coerce_max_results`` owns what
|
||||
"invalid" means (booleans, non-integral floats and ``OverflowError`` all
|
||||
fall back to the default); the 1-100 cap stays here because clamping
|
||||
policy is deliberately per-provider.
|
||||
"""
|
||||
return min(
|
||||
coerce_max_results(value, provider="Serply", logger=logger, default=_DEFAULT_MAX_RESULTS),
|
||||
_SERPLY_MAX_RESULTS,
|
||||
)
|
||||
|
||||
|
||||
def _coerce_vertical(value: object) -> str:
|
||||
@ -197,7 +195,7 @@ def web_search_tool(query: str, max_results: int = 5) -> str:
|
||||
extra = (config.model_extra or {}) if config is not None else {}
|
||||
if "max_results" in extra:
|
||||
max_results = extra["max_results"]
|
||||
max_results = _coerce_max_results(max_results)
|
||||
max_results = _count_for_request(max_results)
|
||||
vertical = _coerce_vertical(extra.get("vertical"))
|
||||
query = _clean_query(query)
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ from deerflow.community.firecrawl import tools as firecrawl_tools
|
||||
from deerflow.community.image_search import tools as image_search_tools
|
||||
from deerflow.community.search_max_results import DEFAULT_MAX_RESULTS, coerce_max_results
|
||||
from deerflow.community.serper import tools as serper_tools
|
||||
from deerflow.community.serply import tools as serply_tools
|
||||
from deerflow.community.specstream import tools as specstream_tools
|
||||
from deerflow.community.youcom import tools as youcom_tools
|
||||
|
||||
@ -45,6 +46,7 @@ SHARED_OWNER_PROVIDERS = {
|
||||
"ddg_search": ("DDG Search", ddg_search_tools),
|
||||
"image_search": ("DDG image search", image_search_tools),
|
||||
"serper": ("Serper", serper_tools),
|
||||
"serply": ("Serply", serply_tools),
|
||||
"fastcrw": ("fastCRW", fastcrw_tools),
|
||||
"firecrawl": ("Firecrawl", firecrawl_tools),
|
||||
"youcom": ("You.com", youcom_tools),
|
||||
@ -62,7 +64,6 @@ DEFERRED_PROVIDERS = {
|
||||
"exa",
|
||||
"groundroute",
|
||||
"searxng",
|
||||
"serply",
|
||||
"sofya",
|
||||
"tencent_wsa",
|
||||
}
|
||||
|
||||
@ -103,25 +103,27 @@ class TestGetApiKey:
|
||||
patcher.stop()
|
||||
|
||||
|
||||
class TestCoerceMaxResults:
|
||||
class TestCountForRequest:
|
||||
def test_returns_value_when_valid(self):
|
||||
from deerflow.community.serply.tools import _coerce_max_results
|
||||
from deerflow.community.serply.tools import _count_for_request
|
||||
|
||||
assert _coerce_max_results(3) == 3
|
||||
assert _coerce_max_results("7") == 7
|
||||
assert _count_for_request(3) == 3
|
||||
assert _count_for_request("7") == 7
|
||||
|
||||
def test_caps_at_serply_maximum(self):
|
||||
from deerflow.community.serply.tools import _coerce_max_results
|
||||
from deerflow.community.serply.tools import _count_for_request
|
||||
|
||||
assert _coerce_max_results(999) == 100
|
||||
assert _count_for_request(999) == 100
|
||||
|
||||
def test_invalid_values_fall_back_to_default(self):
|
||||
from deerflow.community.serply.tools import _coerce_max_results
|
||||
@pytest.mark.parametrize(
|
||||
"raw",
|
||||
["oops", None, 0, -3, True, False, 3.5, float("inf")],
|
||||
ids=["invalid-string", "none", "zero", "negative", "true", "false", "non-integral-float", "yaml-inf"],
|
||||
)
|
||||
def test_invalid_values_fall_back_to_default(self, raw):
|
||||
from deerflow.community.serply.tools import _count_for_request
|
||||
|
||||
assert _coerce_max_results("oops") == 5
|
||||
assert _coerce_max_results(None) == 5
|
||||
assert _coerce_max_results(0) == 5
|
||||
assert _coerce_max_results(-3) == 5
|
||||
assert _count_for_request(raw) == 5
|
||||
|
||||
|
||||
class TestCoerceVertical:
|
||||
@ -376,10 +378,3 @@ class TestWebSearchTool:
|
||||
|
||||
assert result["total_results"] == 1
|
||||
assert mock_get.call_args.kwargs["headers"]["X-Api-Key"] == "env-key"
|
||||
|
||||
|
||||
def test_coerce_max_results_inf_falls_back_to_default():
|
||||
"""A YAML `.inf` max_results must fall back to the default, not crash."""
|
||||
import deerflow.community.serply.tools as serply_mod
|
||||
|
||||
assert serply_mod._coerce_max_results(float("inf")) == serply_mod._DEFAULT_MAX_RESULTS
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user