diff --git a/searx/engines/tavily.py b/searx/engines/tavily.py
index 3913d67e9..e4c77fe83 100644
--- a/searx/engines/tavily.py
+++ b/searx/engines/tavily.py
@@ -6,18 +6,18 @@
Before reporting an issue with this engine,
please consult `API error codes`_.
-Tavily_ search API (AI engine). This engine implements the REST API
+Tavily_ search API (AI engine). This engine implements the REST API
(`POST /search`_) and does not make use of the `Tavily Python Wrapper`_.
-From the API response this engine generates *result items* (shown in the main
+From the API response, this engine generates *result items* (shown in the main
result list) and an *answer result* (shown on top of the main result list).
If the *answer* from Tavily contains an image, the *answer result* is turned
-into a *infobox result*.
+into an *infobox result*.
.. attention::
AI queries take considerably longer to process than queries to conventional
- search engines. The ``timeout`` should therefore also be set considerably
+ search engines. The ``timeout`` should therefore also be set considerably
higher, but it is not recommended to activate AI queries by default
(set ``disabled: true``), as otherwise all user searches will have to wait
for the AI.
@@ -43,7 +43,9 @@ Optional settings are:
- :py:obj:`days`
- :py:obj:`search_depth`
- :py:obj:`max_results`
+- :py:obj:`include_answer`
- :py:obj:`include_images`
+- :py:obj:`include_image_descriptions`
- :py:obj:`include_domains`
- :py:obj:`exclude_domains`
@@ -102,36 +104,42 @@ api_key: str = "unset"
"""Tavily API Key (`Getting started`_)."""
search_depth: str = "basic"
-"""The depth of the search. It can be ``basic`` or ``advanced``. Default is
+"""The depth of the search. It can be ``basic`` or ``advanced``. Default is
``basic`` unless specified otherwise in a given method.
- have an eye on your `Tavily API Credit Deduction`_!
"""
topic: str = ""
-"""The category of the search. This will determine which of tavily's agents
-will be used for the search. Currently: only ``general`` and ``news`` are
-supported and ``general`` will implicitly activate ``include_answer`` in the
-`POST /search`_ API."""
+"""The category of the search. This will determine which of Tavily's agents
+will be used for the search. Currently, only ``general`` and ``news`` are
+supported."""
days: int = 3
"""The number of days back from the current date to include in the search results.
-This specifies the time frame of data to be retrieved. Please note that this
+This specifies the time frame of data to be retrieved. Please note that this
feature is only available when using the ``news`` search topic. Default is 3."""
max_results: int = 5
-"""The maximum number of search results to return. Default is 5."""
+"""The maximum number of search results to return. Default is 5."""
+
+include_answer: bool = True
+"""Include a short answer to the original query, generated by an LLM based on Tavily's
+search results."""
include_images: bool = False
-"""Include a list of query-related images in the response. Turns answer into
-infobox with first image (as far there are any images in the response). Will
-implicitly activate ``include_image_descriptions`` in the `POST /search`_ API
-(adds descriptive text for each image).
+"""Include a list of query-related images in the response. Creates an infobox
+with the first image (as far as there are any images in the response) and the answer,
+if ``include_answer`` is also enabled.
"""
+include_image_descriptions: bool = False
+"""When ``include_images`` is set to True, this option adds descriptive text for
+each image."""
+
include_domains: list[str] = []
"""A list of domains to specifically include in the search results. Default
-is ``[]```, which includes all domains."""
+is ``[]``, which includes all domains."""
exclude_domains: list[str] = []
"""A list of domains to specifically exclude from the search results. Default
@@ -154,13 +162,12 @@ def request(query, params):
}
if include_images:
- data["include_image_descriptions"] = True
+ data["include_image_descriptions"] = include_image_descriptions
if topic == "general":
- data["include_answer"] = True
+ data["include_answer"] = include_answer
elif topic == "news":
- data["topic"] = "news"
data["days"] = days
params["url"] = search_url
@@ -178,33 +185,32 @@ def response(resp):
for result in data.get("results", []):
results.append(
{
- "title": f"[{gettext('ai')}] {result['title']}",
+ "title": result['title'],
"url": result["url"],
- "content": result["content"],
+ "content": f"[{gettext('ai')}] {result['content']}",
"publishedDate": _parse_date(result.get("published_date")),
}
)
img_list = data.get("images")
if img_list:
- content = data.get("answer")
- img_src = img_list[0]
- if isinstance(img_list[0], dict):
- img_src = img_list[0]["url"]
- img_caption = gettext("Image caption") + ": " + img_list[0]["description"]
- if not content:
- gettext("Image caption")
- content = img_caption
- else:
- content += "//" + img_caption
+ result = {
+ "infobox": f"Tavily [{gettext('ai')}]",
+ "img_src": img_list[0],
+ }
- results.append(
- {
- "infobox": f"Tavily [{gettext('ai')}]",
- "img_src": img_src,
- "content": content,
- }
- )
+ content = data.get("answer")
+ if isinstance(img_list[0], dict):
+ result["img_src"] = img_list[0]["url"]
+ img_caption = f"{gettext('Image caption')}: {img_list[0]['description']}"
+ if not content:
+ result["content"] = img_caption
+ else:
+ result["content"] = f"{content}
{img_caption}"
+ elif content:
+ result["content"] = content
+
+ results.append(result)
elif data["answer"]:
results.append({"answer": data["answer"]})