UNPKG

dtamind-components

Version:

Apps integration for Dtamind. Contain Nodes and Credentials.

243 lines 9.05 kB
"use strict"; 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