mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-01 07:03:02 +00:00
fix(search): forward Perplexity search filters (#49344)
This commit is contained in:
parent
969ded2b54
commit
458463a20d
2 changed files with 78 additions and 26 deletions
|
|
@ -84,9 +84,9 @@ class PerplexitySearchConfig(BaseSearchConfig):
|
|||
def transform_search_request(
|
||||
self,
|
||||
query: str | list[str],
|
||||
optional_params: dict,
|
||||
**kwargs,
|
||||
) -> dict:
|
||||
optional_params: dict[str, object],
|
||||
**kwargs: object,
|
||||
) -> dict[str, object]:
|
||||
"""
|
||||
Transform Search request to Perplexity API format.
|
||||
|
||||
|
|
@ -98,11 +98,7 @@ class PerplexitySearchConfig(BaseSearchConfig):
|
|||
|
||||
Args:
|
||||
query: Search query (string or list of strings)
|
||||
optional_params: Optional parameters for the request
|
||||
- max_results: Maximum number of search results (1-20)
|
||||
- search_domain_filter: List of domains to filter (max 20)
|
||||
- max_tokens_per_page: Max tokens per page (default 1024)
|
||||
- country: Country code filter (e.g., 'US', 'GB', 'DE')
|
||||
optional_params: Provider parameters, forwarded unchanged when not None.
|
||||
|
||||
Returns:
|
||||
Dict with typed request data following PerplexitySearchRequest spec
|
||||
|
|
@ -111,24 +107,10 @@ class PerplexitySearchConfig(BaseSearchConfig):
|
|||
"query": query,
|
||||
}
|
||||
|
||||
# Add optional parameters following Perplexity API spec (only if not None)
|
||||
max_results: Final = optional_params.get("max_results")
|
||||
if max_results is not None:
|
||||
request_data["max_results"] = max_results
|
||||
|
||||
search_domain_filter: Final = optional_params.get("search_domain_filter")
|
||||
if search_domain_filter is not None:
|
||||
request_data["search_domain_filter"] = search_domain_filter
|
||||
|
||||
max_tokens_per_page: Final = optional_params.get("max_tokens_per_page")
|
||||
if max_tokens_per_page is not None:
|
||||
request_data["max_tokens_per_page"] = max_tokens_per_page
|
||||
|
||||
country: Final = optional_params.get("country")
|
||||
if country is not None:
|
||||
request_data["country"] = country
|
||||
|
||||
return dict(request_data)
|
||||
return {
|
||||
**{key: value for key, value in optional_params.items() if value is not None},
|
||||
**request_data,
|
||||
}
|
||||
|
||||
def transform_search_response(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -72,6 +72,72 @@ def test_search_sends_max_results_in_request_body(respx_mock: respx.MockRouter)
|
|||
assert [result.url for result in response.results] == ["https://example.com/ml"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("is_async", [False, True])
|
||||
async def test_search_forwards_provider_filters_without_internal_params(
|
||||
respx_mock: respx.MockRouter, httpx_transport: None, is_async: bool
|
||||
) -> None:
|
||||
route: Final = respx_mock.post(PERPLEXITY_SEARCH_URL).respond(json={"results": []})
|
||||
filters: Final = {
|
||||
"search_recency_filter": "week",
|
||||
"search_after_date_filter": "01/01/2026",
|
||||
"search_before_date_filter": "10/01/2026",
|
||||
"last_updated_after_filter": "01/01/2026",
|
||||
"last_updated_before_filter": "10/01/2026",
|
||||
"search_language_filter": ["en"],
|
||||
"search_mode": "academic",
|
||||
"max_tokens": 2048,
|
||||
"search_domain_filter": ["europa.eu"],
|
||||
}
|
||||
params: Final = {
|
||||
"query": "AI Act obligations for model providers",
|
||||
"search_provider": "perplexity",
|
||||
"metadata": {"private": "local-only"},
|
||||
"input_cost_per_query": 0.01,
|
||||
"_litellm_private_marker": "local-only",
|
||||
**filters,
|
||||
}
|
||||
|
||||
if is_async:
|
||||
response = await litellm.asearch(**params)
|
||||
else:
|
||||
response = litellm.search(**params)
|
||||
|
||||
assert response.object == "search"
|
||||
assert json.loads(route.calls.last.request.content) == {
|
||||
"query": "AI Act obligations for model providers",
|
||||
**filters,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("query", ["original query", ["first query", "second query"]])
|
||||
def test_search_request_preserves_query_and_present_values_without_mutating_options(query: str | list[str]) -> None:
|
||||
optional_params: Final[dict[str, object]] = {
|
||||
"query": "replacement query",
|
||||
"search_recency_filter": None,
|
||||
"search_language_filter": [],
|
||||
"max_tokens": 0,
|
||||
"provider_option": {"enabled": False},
|
||||
}
|
||||
original: Final = dict(optional_params)
|
||||
|
||||
body: Final = PerplexitySearchConfig().transform_search_request(
|
||||
query=query,
|
||||
optional_params=optional_params,
|
||||
api_key="transport-only",
|
||||
api_base="https://transport.invalid",
|
||||
headers={"Authorization": "transport-only"},
|
||||
)
|
||||
|
||||
assert body == {
|
||||
"query": query,
|
||||
"search_language_filter": [],
|
||||
"max_tokens": 0,
|
||||
"provider_option": {"enabled": False},
|
||||
}
|
||||
assert optional_params == original
|
||||
|
||||
|
||||
def _transform(payload: object) -> SearchResponse:
|
||||
logging_obj = Logging(
|
||||
model="perplexity/search",
|
||||
|
|
@ -213,11 +279,15 @@ async def test_router_search_with_search_tools(
|
|||
query="latest AI developments",
|
||||
search_tool_name="litellm-search",
|
||||
max_results=3,
|
||||
search_recency_filter="week",
|
||||
search_language_filter=["en"],
|
||||
)
|
||||
|
||||
assert json.loads(route.calls.last.request.content) == {
|
||||
"query": "latest AI developments",
|
||||
"max_results": 3,
|
||||
"search_recency_filter": "week",
|
||||
"search_language_filter": ["en"],
|
||||
}
|
||||
assert response.object == "search"
|
||||
assert [(result.title, result.url, result.snippet) for result in response.results] == [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue