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

158 lines
5.2 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearxngSearch = void 0;
const env_1 = require("@langchain/core/utils/env");
const tools_1 = require("@langchain/core/tools");
/**
* SearxngSearch class represents a meta search engine tool.
* Use this class when you need to answer questions about current events.
* The input should be a search query, and the output is a JSON array of the query results.
*
* note: works best with *agentType*: `structured-chat-zero-shot-react-description`
* https://github.com/searxng/searxng
* @example
* ```typescript
* const executor = AgentExecutor.fromAgentAndTools({
* agent,
* tools: [
* new SearxngSearch({
* params: {
* format: "json",
* engines: "google",
* },
* headers: {},
* }),
* ],
* });
* const result = await executor.invoke({
* input: `What is Langchain? Describe in 50 words`,
* });
* ```
*/
class SearxngSearch extends tools_1.Tool {
static lc_name() {
return "SearxngSearch";
}
get lc_secrets() {
return {
apiBase: "SEARXNG_API_BASE",
};
}
/**
* Constructor for the SearxngSearch class
* @param apiBase Base URL of the Searxng instance
* @param params SearxNG parameters
* @param headers Custom headers
*/
constructor({ apiBase, params, headers, }) {
super(...arguments);
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: "searxng-search"
});
Object.defineProperty(this, "description", {
enumerable: true,
configurable: true,
writable: true,
value: "A meta search engine. Useful for when you need to answer questions about current events. Input should be a search query. Output is a JSON array of the query results"
});
Object.defineProperty(this, "apiBase", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "params", {
enumerable: true,
configurable: true,
writable: true,
value: {
numResults: 10,
pageNumber: 1,
format: "json",
imageProxy: true,
safesearch: 0,
}
});
Object.defineProperty(this, "headers", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.apiBase = (0, env_1.getEnvironmentVariable)("SEARXNG_API_BASE") || apiBase;
this.headers = { "content-type": "application/json", ...headers };
if (!this.apiBase) {
throw new Error(`SEARXNG_API_BASE not set. You can set it as "SEARXNG_API_BASE" in your environment variables.`);
}
if (params) {
this.params = { ...this.params, ...params };
}
}
/**
* Builds the URL for the Searxng search.
* @param path The path for the URL.
* @param parameters The parameters for the URL.
* @param baseUrl The base URL.
* @returns The complete URL as a string.
*/
buildUrl(path, parameters, baseUrl) {
const nonUndefinedParams = Object.entries(parameters)
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => [key, value.toString()]); // Avoid string conversion
const searchParams = new URLSearchParams(nonUndefinedParams);
return `${baseUrl}/${path}?${searchParams}`;
}
async _call(input) {
const queryParams = {
q: input,
...this.params,
};
const url = this.buildUrl("search", queryParams, this.apiBase);
const resp = await fetch(url, {
method: "POST",
headers: this.headers,
signal: AbortSignal.timeout(5 * 1000), // 5 seconds
});
if (!resp.ok) {
throw new Error(resp.statusText);
}
const res = await resp.json();
if (!res.results.length &&
!res.answers.length &&
!res.infoboxes.length &&
!res.suggestions.length) {
return "No good results found.";
}
else if (res.results.length) {
const response = [];
res.results.forEach((r) => {
response.push(JSON.stringify({
title: r.title || "",
link: r.url || "",
snippet: r.content || "",
}));
});
return response.slice(0, this.params?.numResults).toString();
}
else if (res.answers.length) {
return res.answers[0];
}
else if (res.infoboxes.length) {
return res.infoboxes[0]?.content.replaceAll(/<[^>]+>/gi, "");
}
else if (res.suggestions.length) {
let suggestions = "Suggestions: ";
res.suggestions.forEach((s) => {
suggestions += `${s}, `;
});
return suggestions;
}
else {
return "No good results found.";
}
}
}
exports.SearxngSearch = SearxngSearch;