[mod] small tavily engine changes

- add include_image_descriptions & include_answer to engine settings
- move [ai] prefix in results from title to content content
- minor doc fixes
This commit is contained in:
GenericMale 2025-01-23 03:10:17 +01:00
parent 8ab16bb419
commit 1a3ffdb4ea

View File

@ -6,18 +6,18 @@
Before reporting an issue with this engine, Before reporting an issue with this engine,
please consult `API error codes`_. 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`_. (`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). 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 If the *answer* from Tavily contains an image, the *answer result* is turned
into a *infobox result*. into an *infobox result*.
.. attention:: .. attention::
AI queries take considerably longer to process than queries to conventional 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 higher, but it is not recommended to activate AI queries by default
(set ``disabled: true``), as otherwise all user searches will have to wait (set ``disabled: true``), as otherwise all user searches will have to wait
for the AI. for the AI.
@ -43,7 +43,9 @@ Optional settings are:
- :py:obj:`days` - :py:obj:`days`
- :py:obj:`search_depth` - :py:obj:`search_depth`
- :py:obj:`max_results` - :py:obj:`max_results`
- :py:obj:`include_answer`
- :py:obj:`include_images` - :py:obj:`include_images`
- :py:obj:`include_image_descriptions`
- :py:obj:`include_domains` - :py:obj:`include_domains`
- :py:obj:`exclude_domains` - :py:obj:`exclude_domains`
@ -102,36 +104,42 @@ api_key: str = "unset"
"""Tavily API Key (`Getting started`_).""" """Tavily API Key (`Getting started`_)."""
search_depth: str = "basic" 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. ``basic`` unless specified otherwise in a given method.
- have an eye on your `Tavily API Credit Deduction`_! - have an eye on your `Tavily API Credit Deduction`_!
""" """
topic: str = "" topic: str = ""
"""The category of the search. This will determine which of tavily's agents """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 will be used for the search. Currently, only ``general`` and ``news`` are
supported and ``general`` will implicitly activate ``include_answer`` in the supported."""
`POST /search`_ API."""
days: int = 3 days: int = 3
"""The number of days back from the current date to include in the search results. """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.""" feature is only available when using the ``news`` search topic. Default is 3."""
max_results: int = 5 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_images: bool = False
"""Include a list of query-related images in the response. Turns answer into """Include a list of query-related images in the response. Creates an infobox
infobox with first image (as far there are any images in the response). Will with the first image (as far as there are any images in the response) and the answer,
implicitly activate ``include_image_descriptions`` in the `POST /search`_ API if ``include_answer`` is also enabled.
(adds descriptive text for each image).
""" """
include_image_descriptions: bool = False
"""When ``include_images`` is set to True, this option adds descriptive text for
each image."""
include_domains: list[str] = [] include_domains: list[str] = []
"""A list of domains to specifically include in the search results. Default """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] = [] exclude_domains: list[str] = []
"""A list of domains to specifically exclude from the search results. Default """A list of domains to specifically exclude from the search results. Default
@ -154,13 +162,12 @@ def request(query, params):
} }
if include_images: if include_images:
data["include_image_descriptions"] = True data["include_image_descriptions"] = include_image_descriptions
if topic == "general": if topic == "general":
data["include_answer"] = True data["include_answer"] = include_answer
elif topic == "news": elif topic == "news":
data["topic"] = "news"
data["days"] = days data["days"] = days
params["url"] = search_url params["url"] = search_url
@ -178,33 +185,32 @@ def response(resp):
for result in data.get("results", []): for result in data.get("results", []):
results.append( results.append(
{ {
"title": f"[{gettext('ai')}] {result['title']}", "title": result['title'],
"url": result["url"], "url": result["url"],
"content": result["content"], "content": f"[{gettext('ai')}] {result['content']}",
"publishedDate": _parse_date(result.get("published_date")), "publishedDate": _parse_date(result.get("published_date")),
} }
) )
img_list = data.get("images") img_list = data.get("images")
if img_list: if img_list:
content = data.get("answer") result = {
img_src = img_list[0] "infobox": f"Tavily [{gettext('ai')}]",
if isinstance(img_list[0], dict): "img_src": img_list[0],
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
results.append( content = data.get("answer")
{ if isinstance(img_list[0], dict):
"infobox": f"Tavily [{gettext('ai')}]", result["img_src"] = img_list[0]["url"]
"img_src": img_src, img_caption = f"<i>{gettext('Image caption')}</i>: {img_list[0]['description']}"
"content": content, if not content:
} result["content"] = img_caption
) else:
result["content"] = f"{content}<br/>{img_caption}"
elif content:
result["content"] = content
results.append(result)
elif data["answer"]: elif data["answer"]:
results.append({"answer": data["answer"]}) results.append({"answer": data["answer"]})