Skip to content

Commit 1230ebb

Browse files
feat: add TavilyWebSearch component
Adds a new Haystack integration for Tavily, an AI-powered web search API optimized for LLM applications. Implements sync and async search via TavilyClient and AsyncTavilyClient, following the same interface and structure as the existing FirecrawlWebSearch integration. Closes #2961 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c600da8 commit 1230ebb

10 files changed

Lines changed: 693 additions & 0 deletions

File tree

integrations/tavily/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
## [integrations/tavily-v1.0.0] - 2026-03-25
4+
5+
### 🚀 Features
6+
7+
- Add TavilyWebSearch component

integrations/tavily/LICENSE

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Apache License
2+
Version 2.0, January 2004
3+
http://www.apache.org/licenses/
4+
5+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6+
7+
1. Definitions.
8+
9+
"License" shall mean the terms and conditions for use, reproduction, and distribution.
10+
11+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner.
12+
13+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity.
14+
15+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
16+
17+
"Source" form shall mean the preferred form for making modifications.
18+
19+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form.
20+
21+
"Work" shall mean the work of authorship made available under the License.
22+
23+
"Derivative Works" shall mean any work that is based on the Work.
24+
25+
"Contribution" shall mean any work of authorship submitted to the Licensor for inclusion in the Work.
26+
27+
"Contributor" shall mean Licensor and any Legal Entity on behalf of whom a Contribution has been received by the Licensor.
28+
29+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
30+
31+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work.
32+
33+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work; and (d) If the Work includes a "NOTICE" text file, you must include a readable copy of the attribution notices contained within such NOTICE file.
34+
35+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution submitted for inclusion in the Work by You shall be under the terms and conditions of this License.
36+
37+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor.
38+
39+
7. Disclaimer of Warranty. THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
40+
41+
8. Limitation of Liability. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE FOR ANY DAMAGES.
42+
43+
9. Accepting Warranty or Additional Liability. You may offer additional warranty or liability obligations consistent with this License.
44+
45+
END OF TERMS AND CONDITIONS

integrations/tavily/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# tavily-haystack
2+
3+
[![PyPI - Version](https://img.shields.io/pypi/v/tavily-haystack.svg)](https://pypi.org/project/tavily-haystack)
4+
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tavily-haystack.svg)](https://pypi.org/project/tavily-haystack)
5+
6+
Haystack integration for [Tavily](https://tavily.com) — an AI-powered web search API optimized for LLM applications.
7+
8+
## Installation
9+
10+
```bash
11+
pip install tavily-haystack
12+
```
13+
14+
## Usage
15+
16+
```python
17+
from haystack_integrations.components.websearch.tavily import TavilyWebSearch
18+
from haystack.utils import Secret
19+
20+
websearch = TavilyWebSearch(
21+
api_key=Secret.from_env_var("TAVILY_API_KEY"),
22+
top_k=5,
23+
)
24+
result = websearch.run(query="What is Haystack by deepset?")
25+
documents = result["documents"]
26+
links = result["links"]
27+
```
28+
29+
Set your Tavily API key as an environment variable:
30+
31+
```bash
32+
export TAVILY_API_KEY=your-api-key
33+
```
34+
35+
Get your API key at [tavily.com](https://tavily.com).
36+
37+
## License
38+
39+
`tavily-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.

integrations/tavily/pyproject.toml

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
[build-system]
2+
requires = ["hatchling", "hatch-vcs"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "tavily-haystack"
7+
dynamic = ["version"]
8+
description = "Haystack integration for Tavily Web Search"
9+
readme = "README.md"
10+
requires-python = ">=3.10"
11+
license = "Apache-2.0"
12+
keywords = [
13+
"Tavily",
14+
"Haystack",
15+
"Web Search",
16+
"AI Search",
17+
]
18+
authors = [
19+
{ name = "deepset GmbH", email = "info@deepset.ai" },
20+
]
21+
classifiers = [
22+
"License :: OSI Approved :: Apache Software License",
23+
"Development Status :: 4 - Beta",
24+
"Programming Language :: Python",
25+
"Programming Language :: Python :: 3.10",
26+
"Programming Language :: Python :: 3.11",
27+
"Programming Language :: Python :: 3.12",
28+
"Programming Language :: Python :: 3.13",
29+
"Programming Language :: Python :: Implementation :: CPython",
30+
]
31+
dependencies = [
32+
"haystack-ai>=2.24.1",
33+
"tavily-python>=0.5.0",
34+
]
35+
36+
[project.urls]
37+
Documentation = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/tavily#readme"
38+
Issues = "https://github.com/deepset-ai/haystack-core-integrations/issues"
39+
Source = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/tavily"
40+
41+
[tool.hatch.build.targets.wheel]
42+
packages = ["src/haystack_integrations"]
43+
44+
[tool.hatch.version]
45+
source = "vcs"
46+
tag-pattern = 'integrations\/tavily-v(?P<version>.*)'
47+
48+
[tool.hatch.version.raw-options]
49+
root = "../.."
50+
git_describe_command = 'git describe --tags --match="integrations/tavily-v[0-9]*"'
51+
52+
[tool.hatch.envs.default]
53+
installer = "uv"
54+
dependencies = ["haystack-pydoc-tools", "ruff"]
55+
56+
[tool.hatch.envs.default.scripts]
57+
fmt = "ruff check --fix {args}; ruff format {args}"
58+
fmt-check = "ruff check {args} && ruff format --check {args}"
59+
60+
[tool.hatch.envs.test]
61+
dependencies = [
62+
"pytest",
63+
"pytest-asyncio",
64+
"pytest-cov",
65+
"pytest-rerunfailures",
66+
"mypy",
67+
"pip",
68+
]
69+
70+
[tool.hatch.envs.test.scripts]
71+
unit = 'pytest -m "not integration" {args:tests}'
72+
integration = 'pytest -m "integration" {args:tests}'
73+
all = 'pytest {args:tests}'
74+
cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x {args:tests}'
75+
types = "mypy -p haystack_integrations.components.websearch.tavily {args}"
76+
77+
[tool.mypy]
78+
install_types = true
79+
non_interactive = true
80+
check_untyped_defs = true
81+
disallow_incomplete_defs = true
82+
83+
[tool.ruff]
84+
line-length = 120
85+
86+
[tool.ruff.lint]
87+
select = [
88+
"A",
89+
"ANN",
90+
"ARG",
91+
"B",
92+
"C",
93+
"D102",
94+
"D103",
95+
"D205",
96+
"D209",
97+
"D213",
98+
"D417",
99+
"D419",
100+
"DTZ",
101+
"E",
102+
"EM",
103+
"F",
104+
"I",
105+
"ICN",
106+
"ISC",
107+
"N",
108+
"PLC",
109+
"PLE",
110+
"PLR",
111+
"PLW",
112+
"Q",
113+
"RUF",
114+
"S",
115+
"T",
116+
"TID",
117+
"UP",
118+
"W",
119+
"YTT",
120+
]
121+
ignore = [
122+
"B027",
123+
"B008",
124+
"B905",
125+
"S105",
126+
"S106",
127+
"S107",
128+
"ANN401",
129+
"C901",
130+
"PLR0911",
131+
"PLR0912",
132+
"PLR0913",
133+
"PLR0915",
134+
]
135+
unfixable = [
136+
"F401",
137+
]
138+
139+
[tool.ruff.lint.isort]
140+
known-first-party = ["haystack_integrations"]
141+
142+
[tool.ruff.lint.flake8-tidy-imports]
143+
ban-relative-imports = "parents"
144+
145+
[tool.ruff.lint.per-file-ignores]
146+
"tests/**/*" = ["D", "PLR2004", "S101", "TID252", "ANN"]
147+
148+
[tool.coverage.run]
149+
source = ["haystack_integrations"]
150+
branch = true
151+
parallel = false
152+
153+
[tool.coverage.report]
154+
omit = ["*/tests/*", "*/__init__.py"]
155+
show_missing = true
156+
exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]
157+
158+
[tool.pytest.ini_options]
159+
addopts = "--strict-markers"
160+
markers = [
161+
"unit: unit tests",
162+
"integration: integration tests",
163+
]
164+
log_cli = true
165+
asyncio_default_fixture_loop_scope = "function"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-FileCopyrightText: 2026-present deepset GmbH <info@deepset.ai>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0

integrations/tavily/src/haystack_integrations/components/websearch/py.typed

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: 2026-present deepset GmbH <info@deepset.ai>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from haystack_integrations.components.websearch.tavily.tavily_websearch import TavilyWebSearch
6+
7+
__all__ = ["TavilyWebSearch"]

0 commit comments

Comments
 (0)