dtamind-components
Version:
Apps integration for Dtamind. Contain Nodes and Credentials.
243 lines • 9.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tools_1 = require("@langchain/core/tools");
const utils_1 = require("../../../src/utils");
const defaultDesc = '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';
const defaultName = 'searxng-search';
class Searxng_Tools {
constructor() {
this.label = 'SearXNG';
this.name = 'searXNG';
this.version = 3.0;
this.type = 'SearXNG';
this.icon = 'SearXNG.svg';
this.category = 'Tools';
this.description = 'Wrapper around SearXNG - a free internet metasearch engine';
this.inputs = [
{
label: 'Base URL',
name: 'apiBase',
type: 'string',
default: 'http://localhost:8080'
},
{
label: 'Tool Name',
name: 'toolName',
type: 'string',
default: defaultName
},
{
label: 'Tool Description',
name: 'toolDescription',
type: 'string',
rows: 4,
default: defaultDesc
},
{
label: 'Headers',
name: 'headers',
type: 'json',
description: 'Custom headers for the request',
optional: true,
additionalParams: true
},
{
label: 'Format',
name: 'format',
type: 'options',
options: [
{
label: 'JSON',
name: 'json'
},
{
label: 'HTML',
name: 'html'
}
],
default: 'json',
description: 'Format of the response. You need to enable search formats in settings.yml. Refer to <a target="_blank" href="https://docs.dtamindai.com/integrations/langchain/tools/searxng">SearXNG Setup Guide</a> for more details.',
additionalParams: true
},
{
label: 'Categories',
name: 'categories',
description: 'Comma separated list, specifies the active search categories. (see <a target="_blank" href="https://docs.searxng.org/user/configured_engines.html#configured-engines">Configured Engines</a>)',
optional: true,
additionalParams: true,
type: 'string'
},
{
label: 'Engines',
name: 'engines',
description: 'Comma separated list, specifies the active search engines. (see <a target="_blank" href="https://docs.searxng.org/user/configured_engines.html#configured-engines">Configured Engines</a>)',
optional: true,
additionalParams: true,
type: 'string'
},
{
label: 'Language',
name: 'language',
description: 'Code of the language.',
optional: true,
additionalParams: true,
type: 'string'
},
{
label: 'Page No.',
name: 'pageno',
description: 'Search page number.',
optional: true,
additionalParams: true,
type: 'number'
},
{
label: 'Time Range',
name: 'time_range',
description: 'Time range of search for engines which support it. See if an engine supports time range search in the preferences page of an instance.',
optional: true,
additionalParams: true,
type: 'string'
},
{
label: 'Safe Search',
name: 'safesearch',
description: 'Filter search results of engines which support safe search. See if an engine supports safe search in the preferences page of an instance.',
optional: true,
additionalParams: true,
type: 'number'
}
];
this.baseClasses = [this.type, ...(0, utils_1.getBaseClasses)(SearxngSearch)];
}
async init(nodeData, _) {
const apiBase = nodeData.inputs?.apiBase;
const headers = nodeData.inputs?.headers;
const categories = nodeData.inputs?.categories;
const engines = nodeData.inputs?.engines;
const language = nodeData.inputs?.language;
const pageno = nodeData.inputs?.pageno;
const time_range = nodeData.inputs?.time_range;
const safesearch = nodeData.inputs?.safesearch;
const format = nodeData.inputs?.format;
const toolName = nodeData.inputs?.toolName;
const toolDescription = nodeData.inputs?.toolDescription;
const params = {};
if (categories)
params.categories = categories;
if (engines)
params.engines = engines;
if (language)
params.language = language;
if (pageno)
params.pageNumber = parseFloat(pageno);
if (time_range)
params.timeRange = parseFloat(time_range);
if (safesearch)
params.safesearch = safesearch;
if (format)
params.format = format;
let customHeaders = undefined;
if (headers) {
customHeaders = typeof headers === 'string' ? JSON.parse(headers) : headers;
}
const tool = new SearxngSearch({
apiBase,
params,
headers: customHeaders,
toolName,
toolDescription
});
return tool;
}
}
class SearxngSearch extends tools_1.Tool {
static lc_name() {
return 'SearxngSearch';
}
get lc_secrets() {
return {
apiBase: 'SEARXNG_API_BASE'
};
}
constructor({ apiBase, params, headers, toolName, toolDescription }) {
super(...arguments);
this.name = defaultName;
this.description = defaultDesc;
this.params = {
numResults: 10,
pageNumber: 1,
imageProxy: true,
safesearch: 0
};
this.apiBase = 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 };
}
if (toolName) {
this.name = toolName;
}
if (toolDescription) {
this.description = toolDescription;
}
}
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.';
}
}
}
module.exports = { nodeClass: Searxng_Tools };
//# sourceMappingURL=Searxng.js.map