agsamantha/node_modules/@langchain/community/dist/tools/searchapi.cjs
2024-10-02 15:15:21 -05:00

166 lines
5.7 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchApi = void 0;
const env_1 = require("@langchain/core/utils/env");
const tools_1 = require("@langchain/core/tools");
function isJSONObject(value) {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
/**
* SearchApi Class Definition.
*
* Provides a wrapper around the SearchApi.
*
* Ensure you've set the SEARCHAPI_API_KEY environment variable for authentication.
* You can obtain a free API key from https://www.searchapi.io/.
* @example
* ```typescript
* const searchApi = new SearchApi("your-api-key", {
* engine: "google_news",
* });
* const agent = RunnableSequence.from([
* ChatPromptTemplate.fromMessages([
* ["ai", "Answer the following questions using a bulleted list markdown format.""],
* ["human", "{input}"],
* ]),
* new ChatOpenAI({ temperature: 0 }),
* (input: BaseMessageChunk) => ({
* log: "test",
* returnValues: {
* output: input,
* },
* }),
* ]);
* const executor = AgentExecutor.fromAgentAndTools({
* agent,
* tools: [searchApi],
* });
* const res = await executor.invoke({
* input: "What's happening in Ukraine today?"",
* });
* console.log(res);
* ```
*/
class SearchApi extends tools_1.Tool {
static lc_name() {
return "SearchApi";
}
/**
* Converts the SearchApi instance to JSON. This method is not implemented
* and will throw an error if called.
* @returns Throws an error.
*/
toJSON() {
return this.toJSONNotImplemented();
}
constructor(apiKey = (0, env_1.getEnvironmentVariable)("SEARCHAPI_API_KEY"), params = {}) {
super(...arguments);
Object.defineProperty(this, "apiKey", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "params", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: "search"
});
Object.defineProperty(this, "description", {
enumerable: true,
configurable: true,
writable: true,
value: "a search engine. useful for when you need to answer questions about current events. input should be a search query."
});
if (!apiKey) {
throw new Error("SearchApi requires an API key. Please set it as SEARCHAPI_API_KEY in your .env file, or pass it as a parameter to the SearchApi constructor.");
}
this.apiKey = apiKey;
this.params = params;
}
/**
* Builds a URL for the SearchApi request.
* @param parameters The parameters for the request.
* @returns A string representing the built URL.
*/
buildUrl(searchQuery) {
const preparedParams = Object.entries({
engine: "google",
api_key: this.apiKey,
...this.params,
q: searchQuery,
})
.filter(([key, value]) => value !== undefined && value !== null && key !== "apiKey")
.map(([key, value]) => [key, `${value}`]);
const searchParams = new URLSearchParams(preparedParams);
return `https://www.searchapi.io/api/v1/search?${searchParams}`;
}
/** @ignore */
/**
* Calls the SearchAPI.
*
* Accepts an input query and fetches the result from SearchApi.
*
* @param {string} input - Search query.
* @returns {string} - Formatted search results or an error message.
*
* NOTE: This method is the core search handler and processes various types
* of search results including Google organic results, videos, jobs, and images.
*/
async _call(input) {
const resp = await fetch(this.buildUrl(input));
const json = await resp.json();
if (json.error) {
throw new Error(`Failed to load search results from SearchApi due to: ${json.error}`);
}
// Google Search results
if (json.answer_box?.answer) {
return json.answer_box.answer;
}
if (json.answer_box?.snippet) {
return json.answer_box.snippet;
}
if (json.knowledge_graph?.description) {
return json.knowledge_graph.description;
}
// Organic results (Google, Google News)
if (json.organic_results) {
const snippets = json.organic_results
.filter((r) => r.snippet)
.map((r) => r.snippet);
return snippets.join("\n");
}
// Google Jobs results
if (json.jobs) {
const jobDescriptions = json.jobs
.slice(0, 1)
.filter((r) => r.description)
.map((r) => r.description);
return jobDescriptions.join("\n");
}
// Google Videos results
if (json.videos) {
const videoInfo = json.videos
.filter((r) => r.title && r.link)
.map((r) => `Title: "${r.title}" Link: ${r.link}`);
return videoInfo.join("\n");
}
// Google Images results
if (json.images) {
const image_results = json.images.slice(0, 15);
const imageInfo = image_results
.filter((r) => r.title && r.original && isJSONObject(r.original) && r.original.link)
.map((r) => `Title: "${r.title}" Link: ${r.original.link}`);
return imageInfo.join("\n");
}
return "No good search result found";
}
}
exports.SearchApi = SearchApi;