open-webui/backend/open_webui/retrieval/web/tavily.py
Classic298 6e5e5fe6e9
feat: add a Tavily search depth setting (#31308)
Tavily web search always ran at Tavily's default depth (basic), because the search request never sent `search_depth`. The only Tavily depth control in Admin > Settings > Web Search, "Tavily Extract Depth", applies to the Extract API used by the web loader, never to search.

This adds `TAVILY_SEARCH_DEPTH` (env var and persisted setting, default `basic`) and a "Tavily Search Depth" select (ultra-fast, fast, basic, advanced) under the Tavily search engine settings. The value is sent as `search_depth` on every Tavily search request, so admins can set search and extract depth independently, for example fast search with advanced extraction.

The default matches Tavily's own default, so existing setups keep the same behaviour until the setting is changed.

Fixes #29891
2026-09-27 23:15:09 +04:00

53 lines
1.4 KiB
Python

from __future__ import annotations
import logging
import requests
from open_webui.env import TAVILY_API_BASE_URL
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
log = logging.getLogger(__name__)
def search_tavily(
api_key: str,
query: str,
count: int,
filter_list: list[str] | None = None,
search_depth: str = 'basic',
# **kwargs,
) -> list[SearchResult]:
"""Search using Tavily's Search API and return the results as a list of SearchResult objects.
Args:
api_key (str): A Tavily Search API key
query (str): The query to search for
count (int): The maximum number of results to return
search_depth (str): Tavily search depth
Returns:
A list of SearchResult objects.
"""
url = f'{TAVILY_API_BASE_URL}/search'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {api_key}',
}
data = {'query': query, 'max_results': count, 'search_depth': search_depth}
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
json_response = response.json()
results = json_response.get('results', [])
if filter_list:
results = get_filtered_results(results, filter_list)
return [
SearchResult(
link=result['url'],
title=result.get('title', ''),
snippet=result.get('content'),
)
for result in results
]