From c80e0efc46190cb0d0c49d6488d0e722e879fb8d Mon Sep 17 00:00:00 2001 From: Tavily PR Agent Date: Tue, 14 Jul 2026 13:38:54 +0000 Subject: [PATCH] feat: add Tavily as configurable search provider in Express API --- express-api/.env.example | 6 +++++- express-api/index.js | 28 +++++++++++++++++++++------- express-api/package.json | 1 + 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/express-api/.env.example b/express-api/.env.example index ab89e31..81e3a93 100644 --- a/express-api/.env.example +++ b/express-api/.env.example @@ -3,4 +3,8 @@ OPENAI_API_KEY=APIKEYGOESHERE # https://console.groq.com/keys GROQ_API_KEY=APIKEYGOESHERE # https://brave.com/search/api/ -BRAVE_SEARCH_API_KEY=APIKEYGOESHERE \ No newline at end of file +BRAVE_SEARCH_API_KEY=APIKEYGOESHERE +# https://app.tavily.com +TAVILY_API_KEY=APIKEYGOESHERE +# Search provider: 'brave' (default) or 'tavily' +SEARCH_PROVIDER=brave \ No newline at end of file diff --git a/express-api/index.js b/express-api/index.js index 6133c6c..0464586 100644 --- a/express-api/index.js +++ b/express-api/index.js @@ -5,6 +5,7 @@ import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter'; import { OpenAIEmbeddings } from '@langchain/openai'; import { MemoryVectorStore } from 'langchain/vectorstores/memory'; import { BraveSearch } from "@langchain/community/tools/brave_search"; +import { tavily } from "@tavily/core"; import OpenAI from 'openai'; import cheerio from 'cheerio'; import dotenv from 'dotenv'; @@ -44,15 +45,28 @@ app.post('/', async (req, res) => { // 10. Define search engine function async function searchEngineForSources(message) { console.log(`3. Initializing Search Engine Process`); - // 11. Initialize BraveSearch - const loader = new BraveSearch({ apiKey: process.env.BRAVE_SEARCH_API_KEY }); + const searchProvider = process.env.SEARCH_PROVIDER || 'brave'; // 12. Rephrase the message const rephrasedMessage = await rephraseInput(message); - console.log(`6. Rephrased message and got documents from BraveSearch`); - // 13. Get documents from BraveSearch - const docs = await loader.call(rephrasedMessage, { count: numberOfPagesToScan }); - // 14. Normalize data - const normalizedData = normalizeData(docs); + let normalizedData; + if (searchProvider === 'tavily') { + // Tavily search path + console.log(`6. Rephrased message, searching with Tavily`); + const tvly = tavily({ apiKey: process.env.TAVILY_API_KEY }); + const tavilyResponse = await tvly.search(rephrasedMessage, { maxResults: numberOfPagesToScan }); + normalizedData = tavilyResponse.results + .filter((result) => result.title && result.url) + .slice(0, numberOfPagesToScan) + .map(({ title, url }) => ({ title, link: url })); + } else { + // 11. Initialize BraveSearch (default) + const loader = new BraveSearch({ apiKey: process.env.BRAVE_SEARCH_API_KEY }); + console.log(`6. Rephrased message and got documents from BraveSearch`); + // 13. Get documents from BraveSearch + const docs = await loader.call(rephrasedMessage, { count: numberOfPagesToScan }); + // 14. Normalize data + normalizedData = normalizeData(docs); + } // 15. Process and vectorize the content return await Promise.all(normalizedData.map(fetchAndProcess)); } diff --git a/express-api/package.json b/express-api/package.json index 65d22b8..ef3aa4c 100644 --- a/express-api/package.json +++ b/express-api/package.json @@ -15,6 +15,7 @@ "dotenv": "^16.4.5", "express": "^4.18.3", "langchain": "^0.1.25", + "@tavily/core": "^0.0.7", "openai": "^4.28.4" }, "scripts": {