@n8n/n8n-nodes-langchain 1.88.0 → 1.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credentials/OpenRouterApi.credentials.js +1 -1
- package/dist/credentials/OpenRouterApi.credentials.js.map +1 -1
- package/dist/credentials/QdrantApi.credentials.js +1 -3
- package/dist/credentials/QdrantApi.credentials.js.map +1 -1
- package/dist/credentials/SearXngApi.credentials.js +44 -0
- package/dist/credentials/SearXngApi.credentials.js.map +1 -0
- package/dist/known/credentials.json +7 -0
- package/dist/known/nodes.json +4 -0
- package/dist/nodes/agents/Agent/Agent.node.js +1 -1
- package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js +11 -5
- package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js.map +1 -1
- package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js +6 -3
- package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +1 -1
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/nodes/mcp/McpTrigger/McpServer.js +2 -1
- package/dist/nodes/mcp/McpTrigger/McpServer.js.map +1 -1
- package/dist/nodes/tools/ToolCode/ToolCode.node.js +5 -3
- package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
- package/dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js +2 -0
- package/dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js.map +1 -1
- package/dist/nodes/tools/ToolSearXng/ToolSearXng.node.js +136 -0
- package/dist/nodes/tools/ToolSearXng/ToolSearXng.node.js.map +1 -0
- package/dist/nodes/tools/ToolSearXng/searXng.svg +1 -0
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +11 -3
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/ToolWorkflow.node.js +3 -2
- package/dist/nodes/tools/ToolWorkflow/ToolWorkflow.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +5 -2
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/versionDescription.js +7 -2
- package/dist/nodes/tools/ToolWorkflow/v2/versionDescription.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreQdrant/Qdrant.utils.js +54 -0
- package/dist/nodes/vector_store/VectorStoreQdrant/Qdrant.utils.js.map +1 -0
- package/dist/nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.js +5 -4
- package/dist/nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.js.map +1 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/methods/listSearch.js +2 -5
- package/dist/nodes/vector_store/shared/createVectorStoreNode/methods/listSearch.js.map +1 -1
- package/dist/types/credentials.json +3 -2
- package/dist/types/nodes.json +8 -7
- package/dist/utils/helpers.js +5 -0
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/logWrapper.js +2 -1
- package/dist/utils/logWrapper.js.map +1 -1
- package/package.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/mcp/McpTrigger/McpServer.ts"],"sourcesContent":["import type { Tool } from '@langchain/core/tools';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\tJSONRPCMessageSchema,\n\tListToolsRequestSchema,\n\tCallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport type * as express from 'express';\nimport { OperationalError, type Logger } from 'n8n-workflow';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport { FlushingSSEServerTransport } from './FlushingSSEServerTransport';\nimport type { CompressionResponse } from './FlushingSSEServerTransport';\n\n/**\n * Parses the JSONRPC message and checks whether the method used was a tool\n * call. This is necessary in order to not have executions for listing tools\n * and other commands sent by the MCP client\n */\nfunction wasToolCall(body: string) {\n\ttry {\n\t\tconst message: unknown = JSON.parse(body);\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn (\n\t\t\t'method' in parsedMessage &&\n\t\t\t'id' in parsedMessage &&\n\t\t\tparsedMessage?.method === CallToolRequestSchema.shape.method.value\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport class McpServer {\n\tservers: { [sessionId: string]: Server } = {};\n\n\ttransports: { [sessionId: string]: FlushingSSEServerTransport } = {};\n\n\tlogger: Logger;\n\n\tprivate tools: { [sessionId: string]: Tool[] } = {};\n\n\tprivate resolveFunctions: { [sessionId: string]: CallableFunction } = {};\n\n\tconstructor(logger: Logger) {\n\t\tthis.logger = logger;\n\t\tthis.logger.debug('MCP Server created');\n\t}\n\n\tasync connectTransport(postUrl: string, resp: CompressionResponse): Promise<void> {\n\t\tconst transport = new FlushingSSEServerTransport(postUrl, resp);\n\t\tconst server = this.setUpServer();\n\t\tconst { sessionId } = transport;\n\t\tthis.transports[sessionId] = transport;\n\t\tthis.servers[sessionId] = server;\n\n\t\tresp.on('close', async () => {\n\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\tdelete this.tools[sessionId];\n\t\t\tdelete this.resolveFunctions[sessionId];\n\t\t\tdelete this.transports[sessionId];\n\t\t\tdelete this.servers[sessionId];\n\t\t});\n\n\t\tawait server.connect(transport);\n\n\t\t// Make sure we flush the compression middleware, so that it's not waiting for more content to be added to the buffer\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tasync handlePostMessage(req: express.Request, resp: CompressionResponse, connectedTools: Tool[]) {\n\t\tconst sessionId = req.query.sessionId as string;\n\t\tconst transport = this.transports[sessionId];\n\t\tthis.tools[sessionId] = connectedTools;\n\t\tif (transport) {\n\t\t\t// We need to add a promise here because the `handlePostMessage` will send something to the\n\t\t\t// MCP Server, that will run in a different context. This means that the return will happen\n\t\t\t// almost immediately, and will lead to marking the sub-node as \"running\" in the final execution\n\t\t\tawait new Promise(async (resolve) => {\n\t\t\t\tthis.resolveFunctions[sessionId] = resolve;\n\t\t\t\tawait transport.handlePostMessage(req, resp, req.rawBody.toString());\n\t\t\t});\n\t\t\tdelete this.resolveFunctions[sessionId];\n\t\t} else {\n\t\t\tthis.logger.warn(`No transport found for session ${sessionId}`);\n\t\t\tresp.status(401).send('No transport found for sessionId');\n\t\t}\n\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\n\t\tdelete this.tools[sessionId]; // Clean up to avoid keeping all tools in memory\n\n\t\treturn wasToolCall(req.rawBody.toString());\n\t}\n\n\tsetUpServer(): Server {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: 'n8n-mcp-server',\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: { tools: {} },\n\t\t\t},\n\t\t);\n\n\t\tserver.setRequestHandler(ListToolsRequestSchema, async (_, extra: RequestHandlerExtra) => {\n\t\t\tif (!extra.sessionId) {\n\t\t\t\tthrow new OperationalError('Require a sessionId for the listing of tools');\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttools: this.tools[extra.sessionId].map((tool) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tinputSchema: zodToJsonSchema(tool.schema),\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t});\n\n\t\tserver.setRequestHandler(CallToolRequestSchema, async (request, extra: RequestHandlerExtra) => {\n\t\t\tif (!request.params?.name || !request.params?.arguments) {\n\t\t\t\tthrow new OperationalError('Require a name and arguments for the tool call');\n\t\t\t}\n\t\t\tif (!extra.sessionId) {\n\t\t\t\tthrow new OperationalError('Require a sessionId for the tool call');\n\t\t\t}\n\n\t\t\tconst requestedTool: Tool | undefined = this.tools[extra.sessionId].find(\n\t\t\t\t(tool) => tool.name === request.params.name,\n\t\t\t);\n\t\t\tif (!requestedTool) {\n\t\t\t\tthrow new OperationalError('Tool not found');\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await requestedTool.invoke(request.params.arguments);\n\n\t\t\t\tthis.resolveFunctions[extra.sessionId]();\n\n\t\t\t\tthis.logger.debug(`Got request for ${requestedTool.name}, and executed it.`);\n\n\t\t\t\tif (typeof result === 'object') {\n\t\t\t\t\treturn { content: [{ type: 'text', text: JSON.stringify(result) }] };\n\t\t\t\t}\n\t\t\t\tif (typeof result === 'string') {\n\t\t\t\t\treturn { content: [{ type: 'text', text: result }] };\n\t\t\t\t}\n\t\t\t\treturn { content: [{ type: 'text', text: String(result) }] };\n\t\t\t} catch (error) {\n\t\t\t\tthis.logger.error(`Error while executing Tool ${requestedTool.name}: ${error}`);\n\t\t\t\treturn { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] };\n\t\t\t}\n\t\t});\n\n\t\tserver.onclose = () => {\n\t\t\tthis.logger.debug('Closing MCP Server');\n\t\t};\n\t\tserver.onerror = (error: unknown) => {\n\t\t\tthis.logger.error(`MCP Error: ${error}`);\n\t\t};\n\t\treturn server;\n\t}\n}\n\n/**\n * This singleton is shared across the instance, making sure we only have one server to worry about.\n * It needs to stay in memory to keep track of the long-lived connections.\n * It requires a logger at first creation to set everything up.\n */\nexport class McpServerSingleton {\n\tstatic #instance: McpServerSingleton;\n\n\tprivate _serverData: McpServer;\n\n\tprivate constructor(logger: Logger) {\n\t\tthis._serverData = new McpServer(logger);\n\t}\n\n\tstatic instance(logger: Logger): McpServer {\n\t\tif (!McpServerSingleton.#instance) {\n\t\t\tMcpServerSingleton.#instance = new McpServerSingleton(logger);\n\t\t\tlogger.debug('Created singleton for MCP Servers');\n\t\t}\n\n\t\treturn McpServerSingleton.#instance.serverData;\n\t}\n\n\tget serverData() {\n\t\treturn this._serverData;\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/mcp/McpTrigger/McpServer.ts"],"sourcesContent":["import type { Tool } from '@langchain/core/tools';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\tJSONRPCMessageSchema,\n\tListToolsRequestSchema,\n\tCallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport type * as express from 'express';\nimport { OperationalError, type Logger } from 'n8n-workflow';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport { FlushingSSEServerTransport } from './FlushingSSEServerTransport';\nimport type { CompressionResponse } from './FlushingSSEServerTransport';\n\n/**\n * Parses the JSONRPC message and checks whether the method used was a tool\n * call. This is necessary in order to not have executions for listing tools\n * and other commands sent by the MCP client\n */\nfunction wasToolCall(body: string) {\n\ttry {\n\t\tconst message: unknown = JSON.parse(body);\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn (\n\t\t\t'method' in parsedMessage &&\n\t\t\t'id' in parsedMessage &&\n\t\t\tparsedMessage?.method === CallToolRequestSchema.shape.method.value\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport class McpServer {\n\tservers: { [sessionId: string]: Server } = {};\n\n\ttransports: { [sessionId: string]: FlushingSSEServerTransport } = {};\n\n\tlogger: Logger;\n\n\tprivate tools: { [sessionId: string]: Tool[] } = {};\n\n\tprivate resolveFunctions: { [sessionId: string]: CallableFunction } = {};\n\n\tconstructor(logger: Logger) {\n\t\tthis.logger = logger;\n\t\tthis.logger.debug('MCP Server created');\n\t}\n\n\tasync connectTransport(postUrl: string, resp: CompressionResponse): Promise<void> {\n\t\tconst transport = new FlushingSSEServerTransport(postUrl, resp);\n\t\tconst server = this.setUpServer();\n\t\tconst { sessionId } = transport;\n\t\tthis.transports[sessionId] = transport;\n\t\tthis.servers[sessionId] = server;\n\n\t\tresp.on('close', async () => {\n\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\tdelete this.tools[sessionId];\n\t\t\tdelete this.resolveFunctions[sessionId];\n\t\t\tdelete this.transports[sessionId];\n\t\t\tdelete this.servers[sessionId];\n\t\t});\n\n\t\tawait server.connect(transport);\n\n\t\t// Make sure we flush the compression middleware, so that it's not waiting for more content to be added to the buffer\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tasync handlePostMessage(req: express.Request, resp: CompressionResponse, connectedTools: Tool[]) {\n\t\tconst sessionId = req.query.sessionId as string;\n\t\tconst transport = this.transports[sessionId];\n\t\tthis.tools[sessionId] = connectedTools;\n\t\tif (transport) {\n\t\t\t// We need to add a promise here because the `handlePostMessage` will send something to the\n\t\t\t// MCP Server, that will run in a different context. This means that the return will happen\n\t\t\t// almost immediately, and will lead to marking the sub-node as \"running\" in the final execution\n\t\t\tawait new Promise(async (resolve) => {\n\t\t\t\tthis.resolveFunctions[sessionId] = resolve;\n\t\t\t\tawait transport.handlePostMessage(req, resp, req.rawBody.toString());\n\t\t\t});\n\t\t\tdelete this.resolveFunctions[sessionId];\n\t\t} else {\n\t\t\tthis.logger.warn(`No transport found for session ${sessionId}`);\n\t\t\tresp.status(401).send('No transport found for sessionId');\n\t\t}\n\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\n\t\tdelete this.tools[sessionId]; // Clean up to avoid keeping all tools in memory\n\n\t\treturn wasToolCall(req.rawBody.toString());\n\t}\n\n\tsetUpServer(): Server {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: 'n8n-mcp-server',\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: { tools: {} },\n\t\t\t},\n\t\t);\n\n\t\tserver.setRequestHandler(ListToolsRequestSchema, async (_, extra: RequestHandlerExtra) => {\n\t\t\tif (!extra.sessionId) {\n\t\t\t\tthrow new OperationalError('Require a sessionId for the listing of tools');\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttools: this.tools[extra.sessionId].map((tool) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\t// Allow additional properties on tool call input\n\t\t\t\t\t\tinputSchema: zodToJsonSchema(tool.schema, { removeAdditionalStrategy: 'strict' }),\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t});\n\n\t\tserver.setRequestHandler(CallToolRequestSchema, async (request, extra: RequestHandlerExtra) => {\n\t\t\tif (!request.params?.name || !request.params?.arguments) {\n\t\t\t\tthrow new OperationalError('Require a name and arguments for the tool call');\n\t\t\t}\n\t\t\tif (!extra.sessionId) {\n\t\t\t\tthrow new OperationalError('Require a sessionId for the tool call');\n\t\t\t}\n\n\t\t\tconst requestedTool: Tool | undefined = this.tools[extra.sessionId].find(\n\t\t\t\t(tool) => tool.name === request.params.name,\n\t\t\t);\n\t\t\tif (!requestedTool) {\n\t\t\t\tthrow new OperationalError('Tool not found');\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await requestedTool.invoke(request.params.arguments);\n\n\t\t\t\tthis.resolveFunctions[extra.sessionId]();\n\n\t\t\t\tthis.logger.debug(`Got request for ${requestedTool.name}, and executed it.`);\n\n\t\t\t\tif (typeof result === 'object') {\n\t\t\t\t\treturn { content: [{ type: 'text', text: JSON.stringify(result) }] };\n\t\t\t\t}\n\t\t\t\tif (typeof result === 'string') {\n\t\t\t\t\treturn { content: [{ type: 'text', text: result }] };\n\t\t\t\t}\n\t\t\t\treturn { content: [{ type: 'text', text: String(result) }] };\n\t\t\t} catch (error) {\n\t\t\t\tthis.logger.error(`Error while executing Tool ${requestedTool.name}: ${error}`);\n\t\t\t\treturn { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] };\n\t\t\t}\n\t\t});\n\n\t\tserver.onclose = () => {\n\t\t\tthis.logger.debug('Closing MCP Server');\n\t\t};\n\t\tserver.onerror = (error: unknown) => {\n\t\t\tthis.logger.error(`MCP Error: ${error}`);\n\t\t};\n\t\treturn server;\n\t}\n}\n\n/**\n * This singleton is shared across the instance, making sure we only have one server to worry about.\n * It needs to stay in memory to keep track of the long-lived connections.\n * It requires a logger at first creation to set everything up.\n */\nexport class McpServerSingleton {\n\tstatic #instance: McpServerSingleton;\n\n\tprivate _serverData: McpServer;\n\n\tprivate constructor(logger: Logger) {\n\t\tthis._serverData = new McpServer(logger);\n\t}\n\n\tstatic instance(logger: Logger): McpServer {\n\t\tif (!McpServerSingleton.#instance) {\n\t\t\tMcpServerSingleton.#instance = new McpServerSingleton(logger);\n\t\t\tlogger.debug('Created singleton for MCP Servers');\n\t\t}\n\n\t\treturn McpServerSingleton.#instance.serverData;\n\t}\n\n\tget serverData() {\n\t\treturn this._serverData;\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -27,6 +27,7 @@ var import_PythonSandbox = require("n8n-nodes-base/dist/nodes/Code/PythonSandbox
|
|
|
27
27
|
var import_Sandbox = require("n8n-nodes-base/dist/nodes/Code/Sandbox");
|
|
28
28
|
var import_n8n_workflow = require("n8n-workflow");
|
|
29
29
|
var import_descriptions = require("../../../utils/descriptions");
|
|
30
|
+
var import_helpers = require("../../../utils/helpers");
|
|
30
31
|
var import_schemaParsing = require("../../../utils/schemaParsing");
|
|
31
32
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
32
33
|
class ToolCode {
|
|
@@ -37,7 +38,7 @@ class ToolCode {
|
|
|
37
38
|
icon: "fa:code",
|
|
38
39
|
iconColor: "black",
|
|
39
40
|
group: ["transform"],
|
|
40
|
-
version: [1, 1.1],
|
|
41
|
+
version: [1, 1.1, 1.2],
|
|
41
42
|
description: "Write a tool in JS or Python",
|
|
42
43
|
defaults: {
|
|
43
44
|
name: "Code Tool"
|
|
@@ -91,7 +92,7 @@ class ToolCode {
|
|
|
91
92
|
description: "The name of the function to be called, could contain letters, numbers, and underscores only",
|
|
92
93
|
displayOptions: {
|
|
93
94
|
show: {
|
|
94
|
-
"@version": [
|
|
95
|
+
"@version": [1.1]
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
},
|
|
@@ -179,7 +180,8 @@ class ToolCode {
|
|
|
179
180
|
async supplyData(itemIndex) {
|
|
180
181
|
const node = this.getNode();
|
|
181
182
|
const workflowMode = this.getMode();
|
|
182
|
-
const
|
|
183
|
+
const { typeVersion } = node;
|
|
184
|
+
const name = typeVersion <= 1.1 ? this.getNodeParameter("name", itemIndex) : (0, import_helpers.nodeNameToToolName)(node);
|
|
183
185
|
const description = this.getNodeParameter("description", itemIndex);
|
|
184
186
|
const useSchema = this.getNodeParameter("specifyInputSchema", itemIndex);
|
|
185
187
|
const language = this.getNodeParameter("language", itemIndex);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolCode/ToolCode.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport type { JSONSchema7 } from 'json-schema';\nimport { JavaScriptSandbox } from 'n8n-nodes-base/dist/nodes/Code/JavaScriptSandbox';\nimport { PythonSandbox } from 'n8n-nodes-base/dist/nodes/Code/PythonSandbox';\nimport type { Sandbox } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';\nimport { getSandboxContext } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tExecutionError,\n\tIDataObject,\n} from 'n8n-workflow';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\n\nimport {\n\tbuildInputSchemaField,\n\tbuildJsonSchemaExampleField,\n\tschemaTypeField,\n} from '@utils/descriptions';\nimport { convertJsonSchemaToZod, generateSchema } from '@utils/schemaParsing';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport type { DynamicZodObject } from '../../../types/zod.types';\n\nexport class ToolCode implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Code Tool',\n\t\tname: 'toolCode',\n\t\ticon: 'fa:code',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Write a tool in JS or Python',\n\t\tdefaults: {\n\t\t\tname: 'Code Tool',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolcode/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'See an example of a conversational agent with custom tool written in JavaScript <a href=\"/templates/1963\" target=\"_blank\">here</a>.',\n\t\t\t\tname: 'noticeTemplateExample',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'My_Tool',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. My_Tool',\n\t\t\t\tvalidateType: 'string-alphanumeric',\n\t\t\t\tdescription:\n\t\t\t\t\t'The name of the function to be called, could contain letters, numbers, and underscores only',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder:\n\t\t\t\t\t'Call this tool to get a random color. The input should be a string with comma separted names of colors to exclude.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t{\n\t\t\t\tdisplayName: 'Language',\n\t\t\t\tname: 'language',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'JavaScript',\n\t\t\t\t\t\tvalue: 'javaScript',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Python (Beta)',\n\t\t\t\t\t\tvalue: 'python',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'javaScript',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'JavaScript',\n\t\t\t\tname: 'jsCode',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tlanguage: ['javaScript'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\teditor: 'jsEditor',\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'// Example: convert the incoming query to uppercase and return it\\nreturn query.toUpperCase()',\n\t\t\t\t// TODO: Add proper text here later\n\t\t\t\thint: 'You can access the input the tool receives via the input property \"query\". The returned value should be a single string.',\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-description-missing-final-period\n\t\t\t\tdescription: 'E.g. Converts any text to uppercase',\n\t\t\t\tnoDataExpression: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Python',\n\t\t\t\tname: 'pythonCode',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tlanguage: ['python'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\teditor: 'codeNodeEditor', // TODO: create a separate `pythonEditor` component\n\t\t\t\t\teditorLanguage: 'python',\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'# Example: convert the incoming query to uppercase and return it\\nreturn query.upper()',\n\t\t\t\t// TODO: Add proper text here later\n\t\t\t\thint: 'You can access the input the tool receives via the input property \"query\". The returned value should be a single string.',\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-description-missing-final-period\n\t\t\t\tdescription: 'E.g. Converts any text to uppercase',\n\t\t\t\tnoDataExpression: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Specify Input Schema',\n\t\t\t\tname: 'specifyInputSchema',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to specify the schema for the function. This would require the LLM to provide the input in the correct format and would validate it against the schema.',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t\t{ ...schemaTypeField, displayOptions: { show: { specifyInputSchema: [true] } } },\n\t\t\tbuildJsonSchemaExampleField({ showExtraProps: { specifyInputSchema: [true] } }),\n\t\t\tbuildInputSchemaField({ showExtraProps: { specifyInputSchema: [true] } }),\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst workflowMode = this.getMode();\n\n\t\tconst name = this.getNodeParameter('name', itemIndex) as string;\n\t\tconst description = this.getNodeParameter('description', itemIndex) as string;\n\n\t\tconst useSchema = this.getNodeParameter('specifyInputSchema', itemIndex) as boolean;\n\n\t\tconst language = this.getNodeParameter('language', itemIndex) as string;\n\t\tlet code = '';\n\t\tif (language === 'javaScript') {\n\t\t\tcode = this.getNodeParameter('jsCode', itemIndex) as string;\n\t\t} else {\n\t\t\tcode = this.getNodeParameter('pythonCode', itemIndex) as string;\n\t\t}\n\n\t\tconst getSandbox = (query: string | IDataObject, index = 0) => {\n\t\t\tconst context = getSandboxContext.call(this, index);\n\t\t\tcontext.query = query;\n\n\t\t\tlet sandbox: Sandbox;\n\t\t\tif (language === 'javaScript') {\n\t\t\t\tsandbox = new JavaScriptSandbox(context, code, this.helpers);\n\t\t\t} else {\n\t\t\t\tsandbox = new PythonSandbox(context, code, this.helpers);\n\t\t\t}\n\n\t\t\tsandbox.on(\n\t\t\t\t'output',\n\t\t\t\tworkflowMode === 'manual'\n\t\t\t\t\t? this.sendMessageToUI.bind(this)\n\t\t\t\t\t: (...args: unknown[]) =>\n\t\t\t\t\t\t\tconsole.log(`[Workflow \"${this.getWorkflow().id}\"][Node \"${node.name}\"]`, ...args),\n\t\t\t);\n\t\t\treturn sandbox;\n\t\t};\n\n\t\tconst runFunction = async (query: string | IDataObject): Promise<string> => {\n\t\t\tconst sandbox = getSandbox(query, itemIndex);\n\t\t\treturn await sandbox.runCode<string>();\n\t\t};\n\n\t\tconst toolHandler = async (query: string | IDataObject): Promise<string> => {\n\t\t\tconst { index } = this.addInputData(NodeConnectionTypes.AiTool, [[{ json: { query } }]]);\n\n\t\t\tlet response: string = '';\n\t\t\tlet executionError: ExecutionError | undefined;\n\t\t\ttry {\n\t\t\t\tresponse = await runFunction(query);\n\t\t\t} catch (error: unknown) {\n\t\t\t\texecutionError = new NodeOperationError(this.getNode(), error as ExecutionError);\n\t\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t\t}\n\n\t\t\tif (typeof response === 'number') {\n\t\t\t\tresponse = (response as number).toString();\n\t\t\t}\n\n\t\t\tif (typeof response !== 'string') {\n\t\t\t\t// TODO: Do some more testing. Issues here should actually fail the workflow\n\t\t\t\texecutionError = new NodeOperationError(this.getNode(), 'Wrong output type returned', {\n\t\t\t\t\tdescription: `The response property should be a string, but it is an ${typeof response}`,\n\t\t\t\t});\n\t\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t\t}\n\n\t\t\tif (executionError) {\n\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, index, executionError);\n\t\t\t} else {\n\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, index, [[{ json: { response } }]]);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t};\n\n\t\tconst commonToolOptions = {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\tfunc: toolHandler,\n\t\t};\n\n\t\tlet tool: DynamicTool | DynamicStructuredTool | undefined = undefined;\n\n\t\tif (useSchema) {\n\t\t\ttry {\n\t\t\t\t// We initialize these even though one of them will always be empty\n\t\t\t\t// it makes it easier to navigate the ternary operator\n\t\t\t\tconst jsonExample = this.getNodeParameter('jsonSchemaExample', itemIndex, '') as string;\n\t\t\t\tconst inputSchema = this.getNodeParameter('inputSchema', itemIndex, '') as string;\n\n\t\t\t\tconst schemaType = this.getNodeParameter('schemaType', itemIndex) as 'fromJson' | 'manual';\n\t\t\t\tconst jsonSchema =\n\t\t\t\t\tschemaType === 'fromJson'\n\t\t\t\t\t\t? generateSchema(jsonExample)\n\t\t\t\t\t\t: jsonParse<JSONSchema7>(inputSchema);\n\n\t\t\t\tconst zodSchema = convertJsonSchemaToZod<DynamicZodObject>(jsonSchema);\n\n\t\t\t\ttool = new DynamicStructuredTool({\n\t\t\t\t\tschema: zodSchema,\n\t\t\t\t\t...commonToolOptions,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t'Error during parsing of JSON Schema. \\n ' + error,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\ttool = new DynamicTool(commonToolOptions);\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: tool,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolCode/ToolCode.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport type { JSONSchema7 } from 'json-schema';\nimport { JavaScriptSandbox } from 'n8n-nodes-base/dist/nodes/Code/JavaScriptSandbox';\nimport { PythonSandbox } from 'n8n-nodes-base/dist/nodes/Code/PythonSandbox';\nimport type { Sandbox } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';\nimport { getSandboxContext } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tExecutionError,\n\tIDataObject,\n} from 'n8n-workflow';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\n\nimport {\n\tbuildInputSchemaField,\n\tbuildJsonSchemaExampleField,\n\tschemaTypeField,\n} from '@utils/descriptions';\nimport { nodeNameToToolName } from '@utils/helpers';\nimport { convertJsonSchemaToZod, generateSchema } from '@utils/schemaParsing';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport type { DynamicZodObject } from '../../../types/zod.types';\n\nexport class ToolCode implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Code Tool',\n\t\tname: 'toolCode',\n\t\ticon: 'fa:code',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Write a tool in JS or Python',\n\t\tdefaults: {\n\t\t\tname: 'Code Tool',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolcode/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'See an example of a conversational agent with custom tool written in JavaScript <a href=\"/templates/1963\" target=\"_blank\">here</a>.',\n\t\t\t\tname: 'noticeTemplateExample',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'My_Tool',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. My_Tool',\n\t\t\t\tvalidateType: 'string-alphanumeric',\n\t\t\t\tdescription:\n\t\t\t\t\t'The name of the function to be called, could contain letters, numbers, and underscores only',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder:\n\t\t\t\t\t'Call this tool to get a random color. The input should be a string with comma separted names of colors to exclude.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t{\n\t\t\t\tdisplayName: 'Language',\n\t\t\t\tname: 'language',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'JavaScript',\n\t\t\t\t\t\tvalue: 'javaScript',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Python (Beta)',\n\t\t\t\t\t\tvalue: 'python',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'javaScript',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'JavaScript',\n\t\t\t\tname: 'jsCode',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tlanguage: ['javaScript'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\teditor: 'jsEditor',\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'// Example: convert the incoming query to uppercase and return it\\nreturn query.toUpperCase()',\n\t\t\t\t// TODO: Add proper text here later\n\t\t\t\thint: 'You can access the input the tool receives via the input property \"query\". The returned value should be a single string.',\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-description-missing-final-period\n\t\t\t\tdescription: 'E.g. Converts any text to uppercase',\n\t\t\t\tnoDataExpression: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Python',\n\t\t\t\tname: 'pythonCode',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tlanguage: ['python'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\teditor: 'codeNodeEditor', // TODO: create a separate `pythonEditor` component\n\t\t\t\t\teditorLanguage: 'python',\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'# Example: convert the incoming query to uppercase and return it\\nreturn query.upper()',\n\t\t\t\t// TODO: Add proper text here later\n\t\t\t\thint: 'You can access the input the tool receives via the input property \"query\". The returned value should be a single string.',\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-description-missing-final-period\n\t\t\t\tdescription: 'E.g. Converts any text to uppercase',\n\t\t\t\tnoDataExpression: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Specify Input Schema',\n\t\t\t\tname: 'specifyInputSchema',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to specify the schema for the function. This would require the LLM to provide the input in the correct format and would validate it against the schema.',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t\t{ ...schemaTypeField, displayOptions: { show: { specifyInputSchema: [true] } } },\n\t\t\tbuildJsonSchemaExampleField({ showExtraProps: { specifyInputSchema: [true] } }),\n\t\t\tbuildInputSchemaField({ showExtraProps: { specifyInputSchema: [true] } }),\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst workflowMode = this.getMode();\n\n\t\tconst { typeVersion } = node;\n\t\tconst name =\n\t\t\ttypeVersion <= 1.1\n\t\t\t\t? (this.getNodeParameter('name', itemIndex) as string)\n\t\t\t\t: nodeNameToToolName(node);\n\n\t\tconst description = this.getNodeParameter('description', itemIndex) as string;\n\n\t\tconst useSchema = this.getNodeParameter('specifyInputSchema', itemIndex) as boolean;\n\n\t\tconst language = this.getNodeParameter('language', itemIndex) as string;\n\t\tlet code = '';\n\t\tif (language === 'javaScript') {\n\t\t\tcode = this.getNodeParameter('jsCode', itemIndex) as string;\n\t\t} else {\n\t\t\tcode = this.getNodeParameter('pythonCode', itemIndex) as string;\n\t\t}\n\n\t\tconst getSandbox = (query: string | IDataObject, index = 0) => {\n\t\t\tconst context = getSandboxContext.call(this, index);\n\t\t\tcontext.query = query;\n\n\t\t\tlet sandbox: Sandbox;\n\t\t\tif (language === 'javaScript') {\n\t\t\t\tsandbox = new JavaScriptSandbox(context, code, this.helpers);\n\t\t\t} else {\n\t\t\t\tsandbox = new PythonSandbox(context, code, this.helpers);\n\t\t\t}\n\n\t\t\tsandbox.on(\n\t\t\t\t'output',\n\t\t\t\tworkflowMode === 'manual'\n\t\t\t\t\t? this.sendMessageToUI.bind(this)\n\t\t\t\t\t: (...args: unknown[]) =>\n\t\t\t\t\t\t\tconsole.log(`[Workflow \"${this.getWorkflow().id}\"][Node \"${node.name}\"]`, ...args),\n\t\t\t);\n\t\t\treturn sandbox;\n\t\t};\n\n\t\tconst runFunction = async (query: string | IDataObject): Promise<string> => {\n\t\t\tconst sandbox = getSandbox(query, itemIndex);\n\t\t\treturn await sandbox.runCode<string>();\n\t\t};\n\n\t\tconst toolHandler = async (query: string | IDataObject): Promise<string> => {\n\t\t\tconst { index } = this.addInputData(NodeConnectionTypes.AiTool, [[{ json: { query } }]]);\n\n\t\t\tlet response: string = '';\n\t\t\tlet executionError: ExecutionError | undefined;\n\t\t\ttry {\n\t\t\t\tresponse = await runFunction(query);\n\t\t\t} catch (error: unknown) {\n\t\t\t\texecutionError = new NodeOperationError(this.getNode(), error as ExecutionError);\n\t\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t\t}\n\n\t\t\tif (typeof response === 'number') {\n\t\t\t\tresponse = (response as number).toString();\n\t\t\t}\n\n\t\t\tif (typeof response !== 'string') {\n\t\t\t\t// TODO: Do some more testing. Issues here should actually fail the workflow\n\t\t\t\texecutionError = new NodeOperationError(this.getNode(), 'Wrong output type returned', {\n\t\t\t\t\tdescription: `The response property should be a string, but it is an ${typeof response}`,\n\t\t\t\t});\n\t\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t\t}\n\n\t\t\tif (executionError) {\n\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, index, executionError);\n\t\t\t} else {\n\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, index, [[{ json: { response } }]]);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t};\n\n\t\tconst commonToolOptions = {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\tfunc: toolHandler,\n\t\t};\n\n\t\tlet tool: DynamicTool | DynamicStructuredTool | undefined = undefined;\n\n\t\tif (useSchema) {\n\t\t\ttry {\n\t\t\t\t// We initialize these even though one of them will always be empty\n\t\t\t\t// it makes it easier to navigate the ternary operator\n\t\t\t\tconst jsonExample = this.getNodeParameter('jsonSchemaExample', itemIndex, '') as string;\n\t\t\t\tconst inputSchema = this.getNodeParameter('inputSchema', itemIndex, '') as string;\n\n\t\t\t\tconst schemaType = this.getNodeParameter('schemaType', itemIndex) as 'fromJson' | 'manual';\n\t\t\t\tconst jsonSchema =\n\t\t\t\t\tschemaType === 'fromJson'\n\t\t\t\t\t\t? generateSchema(jsonExample)\n\t\t\t\t\t\t: jsonParse<JSONSchema7>(inputSchema);\n\n\t\t\t\tconst zodSchema = convertJsonSchemaToZod<DynamicZodObject>(jsonSchema);\n\n\t\t\t\ttool = new DynamicStructuredTool({\n\t\t\t\t\tschema: zodSchema,\n\t\t\t\t\t...commonToolOptions,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t'Error during parsing of JSON Schema. \\n ' + error,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\ttool = new DynamicTool(commonToolOptions);\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: tool,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -55,6 +55,8 @@ class ToolHttpRequest {
|
|
|
55
55
|
]
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
+
// Replaced by a `usableAsTool` version of the standalone HttpRequest node
|
|
59
|
+
hidden: true,
|
|
58
60
|
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
|
|
59
61
|
inputs: [],
|
|
60
62
|
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolHttpRequest/ToolHttpRequest.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\nimport { DynamicTool } from '@langchain/core/tools';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tIHttpRequestMethods,\n\tIHttpRequestOptions,\n} from 'n8n-workflow';\nimport {\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttryToParseAlphanumericString,\n} from 'n8n-workflow';\n\nimport { N8nTool } from '@utils/N8nTool';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport {\n\tauthenticationProperties,\n\tjsonInput,\n\toptimizeResponseProperties,\n\tparametersCollection,\n\tplaceholderDefinitionsCollection,\n\tspecifyBySelector,\n} from './descriptions';\nimport type { PlaceholderDefinition, ToolParameter } from './interfaces';\nimport {\n\tconfigureHttpRequestFunction,\n\tconfigureResponseOptimizer,\n\textractParametersFromText,\n\tprepareToolDescription,\n\tconfigureToolFunction,\n\tupdateParametersAndOptions,\n\tmakeToolInputSchema,\n} from './utils';\n\nexport class ToolHttpRequest implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'HTTP Request Tool',\n\t\tname: 'toolHttpRequest',\n\t\ticon: { light: 'file:httprequest.svg', dark: 'file:httprequest.dark.svg' },\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Makes an HTTP request and returns the response data',\n\t\tsubtitle: '={{ $parameter.toolDescription }}',\n\t\tdefaults: {\n\t\t\tname: 'HTTP Request',\n\t\t},\n\t\tcredentials: [],\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolhttprequest/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'toolDescription',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription:\n\t\t\t\t\t'Explain to LLM what this tool does, better description would allow LLM to produce expected result',\n\t\t\t\tplaceholder: 'e.g. Get the current weather in the requested city',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Method',\n\t\t\t\tname: 'method',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'DELETE',\n\t\t\t\t\t\tvalue: 'DELETE',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'GET',\n\t\t\t\t\t\tvalue: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'PATCH',\n\t\t\t\t\t\tvalue: 'PATCH',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'POST',\n\t\t\t\t\t\tvalue: 'POST',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'PUT',\n\t\t\t\t\t\tvalue: 'PUT',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'GET',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Tip: You can use a {placeholder} for any part of the request to be filled by the model. Provide more context about them in the placeholders section',\n\t\t\t\tname: 'placeholderNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tplaceholder: 'e.g. http://www.example.com/{path}',\n\t\t\t},\n\t\t\t...authenticationProperties,\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Query Parameters',\n\t\t\t\tname: 'sendQuery',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has query params or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Query Parameters',\n\t\t\t\tname: 'specifyQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Query Parameters',\n\t\t\t\tname: 'parametersQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t\tspecifyQuery: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t\tspecifyQuery: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Headers',\n\t\t\t\tname: 'sendHeaders',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has headers or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Headers',\n\t\t\t\tname: 'specifyHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Header Parameters',\n\t\t\t\tname: 'parametersHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t\tspecifyHeaders: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t\tspecifyHeaders: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Body',\n\t\t\t\tname: 'sendBody',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has body or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Body',\n\t\t\t\tname: 'specifyBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Body Parameters',\n\t\t\t\tname: 'parametersBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t\tspecifyBody: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t\tspecifyBody: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\tplaceholderDefinitionsCollection,\n\t\t\t...optimizeResponseProperties,\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst name = this.getNode().name.replace(/ /g, '_');\n\t\ttry {\n\t\t\ttryToParseAlphanumericString(name);\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.getNode(),\n\t\t\t\t'The name of this tool is not a valid alphanumeric string',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Only alphanumeric characters and underscores are allowed in the tool's name, and the name cannot start with a number\",\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst toolDescription = this.getNodeParameter('toolDescription', itemIndex) as string;\n\t\tconst sendQuery = this.getNodeParameter('sendQuery', itemIndex, false) as boolean;\n\t\tconst sendHeaders = this.getNodeParameter('sendHeaders', itemIndex, false) as boolean;\n\t\tconst sendBody = this.getNodeParameter('sendBody', itemIndex, false) as boolean;\n\n\t\tconst requestOptions: IHttpRequestOptions = {\n\t\t\tmethod: this.getNodeParameter('method', itemIndex, 'GET') as IHttpRequestMethods,\n\t\t\turl: this.getNodeParameter('url', itemIndex) as string,\n\t\t\tqs: {},\n\t\t\theaders: {\n\t\t\t\t// FIXME: This is a workaround to prevent the node from sending a default User-Agent (`n8n`) when the header is not set.\n\t\t\t\t// Needs to be replaced with a proper fix after NODE-1777 is resolved\n\t\t\t\t'User-Agent': undefined,\n\t\t\t},\n\t\t\tbody: {},\n\t\t\t// We will need a full response object later to extract the headers and check the response's content type.\n\t\t\treturnFullResponse: true,\n\t\t};\n\n\t\tconst authentication = this.getNodeParameter('authentication', itemIndex, 'none') as\n\t\t\t| 'predefinedCredentialType'\n\t\t\t| 'genericCredentialType'\n\t\t\t| 'none';\n\n\t\tif (authentication !== 'none') {\n\t\t\tconst domain = new URL(requestOptions.url).hostname;\n\t\t\tif (domain.includes('{') && domain.includes('}')) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\"Can't use a placeholder for the domain when using authentication\",\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'This is for security reasons, to prevent the model accidentally sending your credentials to an unauthorized domain',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst httpRequest = await configureHttpRequestFunction(this, authentication, itemIndex);\n\t\tconst optimizeResponse = configureResponseOptimizer(this, itemIndex);\n\n\t\tconst rawRequestOptions: { [key: string]: string } = {\n\t\t\tqs: '',\n\t\t\theaders: '',\n\t\t\tbody: '',\n\t\t};\n\n\t\tconst placeholdersDefinitions = (\n\t\t\tthis.getNodeParameter(\n\t\t\t\t'placeholderDefinitions.values',\n\t\t\t\titemIndex,\n\t\t\t\t[],\n\t\t\t) as PlaceholderDefinition[]\n\t\t).map((p) => {\n\t\t\tif (p.name.startsWith('{') && p.name.endsWith('}')) {\n\t\t\t\tp.name = p.name.slice(1, -1);\n\t\t\t}\n\t\t\treturn p;\n\t\t});\n\n\t\tconst toolParameters: ToolParameter[] = [];\n\n\t\ttoolParameters.push(\n\t\t\t...extractParametersFromText(placeholdersDefinitions, requestOptions.url, 'path'),\n\t\t);\n\n\t\tif (sendQuery) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'qs',\n\t\t\t\tinputTypePropertyName: 'specifyQuery',\n\t\t\t\tjsonPropertyName: 'jsonQuery',\n\t\t\t\tparametersPropertyName: 'parametersQuery.values',\n\t\t\t});\n\t\t}\n\n\t\tif (sendHeaders) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'headers',\n\t\t\t\tinputTypePropertyName: 'specifyHeaders',\n\t\t\t\tjsonPropertyName: 'jsonHeaders',\n\t\t\t\tparametersPropertyName: 'parametersHeaders.values',\n\t\t\t});\n\t\t}\n\n\t\tif (sendBody) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'body',\n\t\t\t\tinputTypePropertyName: 'specifyBody',\n\t\t\t\tjsonPropertyName: 'jsonBody',\n\t\t\t\tparametersPropertyName: 'parametersBody.values',\n\t\t\t});\n\t\t}\n\n\t\tfor (const placeholder of placeholdersDefinitions) {\n\t\t\tif (!toolParameters.find((parameter) => parameter.name === placeholder.name)) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t`Misconfigured placeholder '${placeholder.name}'`,\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"This placeholder is defined in the 'Placeholder Definitions' but isn't used anywhere. Either remove the definition, or add the placeholder to a part of the request.\",\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst func = configureToolFunction(\n\t\t\tthis,\n\t\t\titemIndex,\n\t\t\ttoolParameters,\n\t\t\trequestOptions,\n\t\t\trawRequestOptions,\n\t\t\thttpRequest,\n\t\t\toptimizeResponse,\n\t\t);\n\n\t\tlet tool: DynamicTool | N8nTool;\n\n\t\t// If the node version is 1.1 or higher, we use the N8nTool wrapper:\n\t\t// it allows to use tool as a DynamicStructuredTool and have a fallback to DynamicTool\n\t\tif (this.getNode().typeVersion >= 1.1) {\n\t\t\tconst schema = makeToolInputSchema(toolParameters);\n\n\t\t\ttool = new N8nTool(this, {\n\t\t\t\tname,\n\t\t\t\tdescription: toolDescription,\n\t\t\t\tfunc,\n\t\t\t\tschema,\n\t\t\t});\n\t\t} else {\n\t\t\t// Keep the old behavior for nodes with version 1.0\n\t\t\tconst description = prepareToolDescription(toolDescription, toolParameters);\n\t\t\ttool = new DynamicTool({ name, description, func });\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: tool,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolHttpRequest/ToolHttpRequest.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\nimport { DynamicTool } from '@langchain/core/tools';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tIHttpRequestMethods,\n\tIHttpRequestOptions,\n} from 'n8n-workflow';\nimport {\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttryToParseAlphanumericString,\n} from 'n8n-workflow';\n\nimport { N8nTool } from '@utils/N8nTool';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport {\n\tauthenticationProperties,\n\tjsonInput,\n\toptimizeResponseProperties,\n\tparametersCollection,\n\tplaceholderDefinitionsCollection,\n\tspecifyBySelector,\n} from './descriptions';\nimport type { PlaceholderDefinition, ToolParameter } from './interfaces';\nimport {\n\tconfigureHttpRequestFunction,\n\tconfigureResponseOptimizer,\n\textractParametersFromText,\n\tprepareToolDescription,\n\tconfigureToolFunction,\n\tupdateParametersAndOptions,\n\tmakeToolInputSchema,\n} from './utils';\n\nexport class ToolHttpRequest implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'HTTP Request Tool',\n\t\tname: 'toolHttpRequest',\n\t\ticon: { light: 'file:httprequest.svg', dark: 'file:httprequest.dark.svg' },\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Makes an HTTP request and returns the response data',\n\t\tsubtitle: '={{ $parameter.toolDescription }}',\n\t\tdefaults: {\n\t\t\tname: 'HTTP Request',\n\t\t},\n\t\tcredentials: [],\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolhttprequest/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// Replaced by a `usableAsTool` version of the standalone HttpRequest node\n\t\thidden: true,\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Description',\n\t\t\t\tname: 'toolDescription',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription:\n\t\t\t\t\t'Explain to LLM what this tool does, better description would allow LLM to produce expected result',\n\t\t\t\tplaceholder: 'e.g. Get the current weather in the requested city',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Method',\n\t\t\t\tname: 'method',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'DELETE',\n\t\t\t\t\t\tvalue: 'DELETE',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'GET',\n\t\t\t\t\t\tvalue: 'GET',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'PATCH',\n\t\t\t\t\t\tvalue: 'PATCH',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'POST',\n\t\t\t\t\t\tvalue: 'POST',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'PUT',\n\t\t\t\t\t\tvalue: 'PUT',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'GET',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Tip: You can use a {placeholder} for any part of the request to be filled by the model. Provide more context about them in the placeholders section',\n\t\t\t\tname: 'placeholderNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'URL',\n\t\t\t\tname: 'url',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tplaceholder: 'e.g. http://www.example.com/{path}',\n\t\t\t},\n\t\t\t...authenticationProperties,\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Query Parameters',\n\t\t\t\tname: 'sendQuery',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has query params or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Query Parameters',\n\t\t\t\tname: 'specifyQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Query Parameters',\n\t\t\t\tname: 'parametersQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t\tspecifyQuery: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonQuery',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendQuery: [true],\n\t\t\t\t\t\tspecifyQuery: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Headers',\n\t\t\t\tname: 'sendHeaders',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has headers or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Headers',\n\t\t\t\tname: 'specifyHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Header Parameters',\n\t\t\t\tname: 'parametersHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t\tspecifyHeaders: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonHeaders',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendHeaders: [true],\n\t\t\t\t\t\tspecifyHeaders: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\t{\n\t\t\t\tdisplayName: 'Send Body',\n\t\t\t\tname: 'sendBody',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether the request has body or not',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...specifyBySelector,\n\t\t\t\tdisplayName: 'Specify Body',\n\t\t\t\tname: 'specifyBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...parametersCollection,\n\t\t\t\tdisplayName: 'Body Parameters',\n\t\t\t\tname: 'parametersBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t\tspecifyBody: ['keypair'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonInput,\n\t\t\t\tname: 'jsonBody',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tsendBody: [true],\n\t\t\t\t\t\tspecifyBody: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t//----------------------------------------------------------------\n\t\t\tplaceholderDefinitionsCollection,\n\t\t\t...optimizeResponseProperties,\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst name = this.getNode().name.replace(/ /g, '_');\n\t\ttry {\n\t\t\ttryToParseAlphanumericString(name);\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.getNode(),\n\t\t\t\t'The name of this tool is not a valid alphanumeric string',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Only alphanumeric characters and underscores are allowed in the tool's name, and the name cannot start with a number\",\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst toolDescription = this.getNodeParameter('toolDescription', itemIndex) as string;\n\t\tconst sendQuery = this.getNodeParameter('sendQuery', itemIndex, false) as boolean;\n\t\tconst sendHeaders = this.getNodeParameter('sendHeaders', itemIndex, false) as boolean;\n\t\tconst sendBody = this.getNodeParameter('sendBody', itemIndex, false) as boolean;\n\n\t\tconst requestOptions: IHttpRequestOptions = {\n\t\t\tmethod: this.getNodeParameter('method', itemIndex, 'GET') as IHttpRequestMethods,\n\t\t\turl: this.getNodeParameter('url', itemIndex) as string,\n\t\t\tqs: {},\n\t\t\theaders: {\n\t\t\t\t// FIXME: This is a workaround to prevent the node from sending a default User-Agent (`n8n`) when the header is not set.\n\t\t\t\t// Needs to be replaced with a proper fix after NODE-1777 is resolved\n\t\t\t\t'User-Agent': undefined,\n\t\t\t},\n\t\t\tbody: {},\n\t\t\t// We will need a full response object later to extract the headers and check the response's content type.\n\t\t\treturnFullResponse: true,\n\t\t};\n\n\t\tconst authentication = this.getNodeParameter('authentication', itemIndex, 'none') as\n\t\t\t| 'predefinedCredentialType'\n\t\t\t| 'genericCredentialType'\n\t\t\t| 'none';\n\n\t\tif (authentication !== 'none') {\n\t\t\tconst domain = new URL(requestOptions.url).hostname;\n\t\t\tif (domain.includes('{') && domain.includes('}')) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\"Can't use a placeholder for the domain when using authentication\",\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'This is for security reasons, to prevent the model accidentally sending your credentials to an unauthorized domain',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst httpRequest = await configureHttpRequestFunction(this, authentication, itemIndex);\n\t\tconst optimizeResponse = configureResponseOptimizer(this, itemIndex);\n\n\t\tconst rawRequestOptions: { [key: string]: string } = {\n\t\t\tqs: '',\n\t\t\theaders: '',\n\t\t\tbody: '',\n\t\t};\n\n\t\tconst placeholdersDefinitions = (\n\t\t\tthis.getNodeParameter(\n\t\t\t\t'placeholderDefinitions.values',\n\t\t\t\titemIndex,\n\t\t\t\t[],\n\t\t\t) as PlaceholderDefinition[]\n\t\t).map((p) => {\n\t\t\tif (p.name.startsWith('{') && p.name.endsWith('}')) {\n\t\t\t\tp.name = p.name.slice(1, -1);\n\t\t\t}\n\t\t\treturn p;\n\t\t});\n\n\t\tconst toolParameters: ToolParameter[] = [];\n\n\t\ttoolParameters.push(\n\t\t\t...extractParametersFromText(placeholdersDefinitions, requestOptions.url, 'path'),\n\t\t);\n\n\t\tif (sendQuery) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'qs',\n\t\t\t\tinputTypePropertyName: 'specifyQuery',\n\t\t\t\tjsonPropertyName: 'jsonQuery',\n\t\t\t\tparametersPropertyName: 'parametersQuery.values',\n\t\t\t});\n\t\t}\n\n\t\tif (sendHeaders) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'headers',\n\t\t\t\tinputTypePropertyName: 'specifyHeaders',\n\t\t\t\tjsonPropertyName: 'jsonHeaders',\n\t\t\t\tparametersPropertyName: 'parametersHeaders.values',\n\t\t\t});\n\t\t}\n\n\t\tif (sendBody) {\n\t\t\tupdateParametersAndOptions({\n\t\t\t\tctx: this,\n\t\t\t\titemIndex,\n\t\t\t\ttoolParameters,\n\t\t\t\tplaceholdersDefinitions,\n\t\t\t\trequestOptions,\n\t\t\t\trawRequestOptions,\n\t\t\t\trequestOptionsProperty: 'body',\n\t\t\t\tinputTypePropertyName: 'specifyBody',\n\t\t\t\tjsonPropertyName: 'jsonBody',\n\t\t\t\tparametersPropertyName: 'parametersBody.values',\n\t\t\t});\n\t\t}\n\n\t\tfor (const placeholder of placeholdersDefinitions) {\n\t\t\tif (!toolParameters.find((parameter) => parameter.name === placeholder.name)) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t`Misconfigured placeholder '${placeholder.name}'`,\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"This placeholder is defined in the 'Placeholder Definitions' but isn't used anywhere. Either remove the definition, or add the placeholder to a part of the request.\",\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst func = configureToolFunction(\n\t\t\tthis,\n\t\t\titemIndex,\n\t\t\ttoolParameters,\n\t\t\trequestOptions,\n\t\t\trawRequestOptions,\n\t\t\thttpRequest,\n\t\t\toptimizeResponse,\n\t\t);\n\n\t\tlet tool: DynamicTool | N8nTool;\n\n\t\t// If the node version is 1.1 or higher, we use the N8nTool wrapper:\n\t\t// it allows to use tool as a DynamicStructuredTool and have a fallback to DynamicTool\n\t\tif (this.getNode().typeVersion >= 1.1) {\n\t\t\tconst schema = makeToolInputSchema(toolParameters);\n\n\t\t\ttool = new N8nTool(this, {\n\t\t\t\tname,\n\t\t\t\tdescription: toolDescription,\n\t\t\t\tfunc,\n\t\t\t\tschema,\n\t\t\t});\n\t\t} else {\n\t\t\t// Keep the old behavior for nodes with version 1.0\n\t\t\tconst description = prepareToolDescription(toolDescription, toolParameters);\n\t\t\ttool = new DynamicTool({ name, description, func });\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: tool,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var ToolSearXng_node_exports = {};
|
|
20
|
+
__export(ToolSearXng_node_exports, {
|
|
21
|
+
ToolSearXng: () => ToolSearXng
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(ToolSearXng_node_exports);
|
|
24
|
+
var import_searxng_search = require("@langchain/community/tools/searxng_search");
|
|
25
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
26
|
+
var import_logWrapper = require("../../../utils/logWrapper");
|
|
27
|
+
var import_sharedFields = require("../../../utils/sharedFields");
|
|
28
|
+
class ToolSearXng {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.description = {
|
|
31
|
+
displayName: "SearXNG",
|
|
32
|
+
name: "toolSearXng",
|
|
33
|
+
icon: "file:searXng.svg",
|
|
34
|
+
group: ["transform"],
|
|
35
|
+
version: 1,
|
|
36
|
+
description: "Search in SearXNG",
|
|
37
|
+
defaults: {
|
|
38
|
+
name: "SearXNG"
|
|
39
|
+
},
|
|
40
|
+
codex: {
|
|
41
|
+
categories: ["AI"],
|
|
42
|
+
subcategories: {
|
|
43
|
+
AI: ["Tools"],
|
|
44
|
+
Tools: ["Other Tools"]
|
|
45
|
+
},
|
|
46
|
+
resources: {
|
|
47
|
+
primaryDocumentation: [
|
|
48
|
+
{
|
|
49
|
+
url: "https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolsearxng"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
inputs: [],
|
|
55
|
+
outputs: [import_n8n_workflow.NodeConnectionTypes.AiTool],
|
|
56
|
+
outputNames: ["Tool"],
|
|
57
|
+
credentials: [
|
|
58
|
+
{
|
|
59
|
+
name: "searXngApi",
|
|
60
|
+
required: true
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
properties: [
|
|
64
|
+
(0, import_sharedFields.getConnectionHintNoticeField)([import_n8n_workflow.NodeConnectionTypes.AiAgent]),
|
|
65
|
+
{
|
|
66
|
+
displayName: "Options",
|
|
67
|
+
name: "options",
|
|
68
|
+
type: "collection",
|
|
69
|
+
placeholder: "Add Option",
|
|
70
|
+
default: {},
|
|
71
|
+
options: [
|
|
72
|
+
{
|
|
73
|
+
displayName: "Number of Results",
|
|
74
|
+
name: "numResults",
|
|
75
|
+
type: "number",
|
|
76
|
+
default: 10
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
displayName: "Search Page Number",
|
|
80
|
+
name: "pageNumber",
|
|
81
|
+
type: "number",
|
|
82
|
+
default: 1
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
displayName: "Language",
|
|
86
|
+
name: "language",
|
|
87
|
+
type: "string",
|
|
88
|
+
default: "en",
|
|
89
|
+
description: 'Defines the language to use. It\'s a two-letter language code. (e.g., `en` for English, `es` for Spanish, or `fr` for French). Head to <a href="https://docs.searxng.org/user/search-syntax.html#select-language">SearXNG search syntax page</a> for more info.'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
displayName: "Safe Search",
|
|
93
|
+
name: "safesearch",
|
|
94
|
+
type: "options",
|
|
95
|
+
options: [
|
|
96
|
+
{
|
|
97
|
+
name: "None",
|
|
98
|
+
value: 0
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "Moderate",
|
|
102
|
+
value: 1
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "Strict",
|
|
106
|
+
value: 2
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
default: 0,
|
|
110
|
+
description: "Filter search results of engines which support safe search"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async supplyData(itemIndex) {
|
|
118
|
+
const credentials = await this.getCredentials("searXngApi");
|
|
119
|
+
const options = this.getNodeParameter("options", itemIndex);
|
|
120
|
+
const tool = new import_searxng_search.SearxngSearch({
|
|
121
|
+
apiBase: credentials.apiUrl,
|
|
122
|
+
headers: {
|
|
123
|
+
Accept: "application/json"
|
|
124
|
+
},
|
|
125
|
+
params: options
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
response: (0, import_logWrapper.logWrapper)(tool, this)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
133
|
+
0 && (module.exports = {
|
|
134
|
+
ToolSearXng
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=ToolSearXng.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolSearXng/ToolSearXng.node.ts"],"sourcesContent":["import { SearxngSearch } from '@langchain/community/tools/searxng_search';\nimport { NodeConnectionTypes } from 'n8n-workflow';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\ntype Options = {\n\tnumResults: number;\n\tpageNumber: number;\n\tlanguage: string;\n\tsafesearch: 0 | 1 | 2;\n};\n\nexport class ToolSearXng implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'SearXNG',\n\t\tname: 'toolSearXng',\n\t\ticon: 'file:searXng.svg',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Search in SearXNG',\n\t\tdefaults: {\n\t\t\tname: 'SearXNG',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Other Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolsearxng',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'searXngApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Number of Results',\n\t\t\t\t\t\tname: 'numResults',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdefault: 10,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Search Page Number',\n\t\t\t\t\t\tname: 'pageNumber',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Language',\n\t\t\t\t\t\tname: 'language',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: 'en',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Defines the language to use. It\\'s a two-letter language code. (e.g., `en` for English, `es` for Spanish, or `fr` for French). Head to <a href=\"https://docs.searxng.org/user/search-syntax.html#select-language\">SearXNG search syntax page</a> for more info.',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Safe Search',\n\t\t\t\t\t\tname: 'safesearch',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\t\t\tvalue: 0,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Moderate',\n\t\t\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Strict',\n\t\t\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\tdescription: 'Filter search results of engines which support safe search',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials<{ apiUrl: string }>('searXngApi');\n\t\tconst options = this.getNodeParameter('options', itemIndex) as Options;\n\n\t\tconst tool = new SearxngSearch({\n\t\t\tapiBase: credentials.apiUrl,\n\t\t\theaders: {\n\t\t\t\tAccept: 'application/json',\n\t\t\t},\n\t\t\tparams: options,\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: logWrapper(tool, this),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA8B;AAC9B,0BAAoC;AAQpC,wBAA2B;AAC3B,0BAA6C;AAStC,MAAM,YAAiC;AAAA,EAAvC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,OAAO;AAAA,UACZ,OAAO,CAAC,aAAa;AAAA,QACtB;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,SAAS,CAAC,wCAAoB,MAAM;AAAA,MACpC,aAAa,CAAC,MAAM;AAAA,MACpB,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,YAAY;AAAA,YACX,kDAA6B,CAAC,wCAAoB,OAAO,CAAC;AAAA,QAC1D;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,YACV;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,YACV;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,YACF;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,cACD;AAAA,cACA,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,cAAc,MAAM,KAAK,eAAmC,YAAY;AAC9E,UAAM,UAAU,KAAK,iBAAiB,WAAW,SAAS;AAE1D,UAAM,OAAO,IAAI,oCAAc;AAAA,MAC9B,SAAS,YAAY;AAAA,MACrB,SAAS;AAAA,QACR,QAAQ;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,IACT,CAAC;AAED,WAAO;AAAA,MACN,cAAU,8BAAW,MAAM,IAAI;AAAA,IAChC;AAAA,EACD;AACD;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="92mm" viewBox="0 0 92 92" width="92mm" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-40.921303 -17.416526)"><g fill="none"><circle cx="75" cy="92" r="0" stroke="#000" stroke-width="12"/><circle cx="75.921" cy="53.903" r="30" stroke="#3050ff" stroke-width="10"/><path d="m67.514849 37.91524a18 18 0 0 1 21.051475 3.312407 18 18 0 0 1 3.137312 21.078282" stroke="#3050ff" stroke-width="5"/></g><path d="m3.706 122.09h18.846v39.963h-18.846z" fill="#3050ff" transform="matrix(.69170581 -.72217939 .72217939 .69170581 0 0)"/></g></svg>
|
|
@@ -24,6 +24,7 @@ module.exports = __toCommonJS(ToolVectorStore_node_exports);
|
|
|
24
24
|
var import_chains = require("langchain/chains");
|
|
25
25
|
var import_tools = require("langchain/tools");
|
|
26
26
|
var import_n8n_workflow = require("n8n-workflow");
|
|
27
|
+
var import_helpers = require("../../../utils/helpers");
|
|
27
28
|
var import_logWrapper = require("../../../utils/logWrapper");
|
|
28
29
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
29
30
|
class ToolVectorStore {
|
|
@@ -34,7 +35,7 @@ class ToolVectorStore {
|
|
|
34
35
|
icon: "fa:database",
|
|
35
36
|
iconColor: "black",
|
|
36
37
|
group: ["transform"],
|
|
37
|
-
version: [1],
|
|
38
|
+
version: [1, 1.1],
|
|
38
39
|
description: "Answer questions with a vector store",
|
|
39
40
|
defaults: {
|
|
40
41
|
name: "Answer questions with a vector store"
|
|
@@ -80,7 +81,12 @@ class ToolVectorStore {
|
|
|
80
81
|
default: "",
|
|
81
82
|
placeholder: "e.g. users_info",
|
|
82
83
|
validateType: "string-alphanumeric",
|
|
83
|
-
description: "Name of the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question."
|
|
84
|
+
description: "Name of the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question.",
|
|
85
|
+
displayOptions: {
|
|
86
|
+
show: {
|
|
87
|
+
"@version": [1]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
84
90
|
},
|
|
85
91
|
{
|
|
86
92
|
displayName: "Description of Data",
|
|
@@ -104,7 +110,9 @@ class ToolVectorStore {
|
|
|
104
110
|
};
|
|
105
111
|
}
|
|
106
112
|
async supplyData(itemIndex) {
|
|
107
|
-
const
|
|
113
|
+
const node = this.getNode();
|
|
114
|
+
const { typeVersion } = node;
|
|
115
|
+
const name = typeVersion <= 1 ? this.getNodeParameter("name", itemIndex) : (0, import_helpers.nodeNameToToolName)(node);
|
|
108
116
|
const toolDescription = this.getNodeParameter("description", itemIndex);
|
|
109
117
|
const topK = this.getNodeParameter("topK", itemIndex, 4);
|
|
110
118
|
const vectorStore = await this.getInputConnectionData(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolVectorStore/ToolVectorStore.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { VectorStore } from '@langchain/core/vectorstores';\nimport { VectorDBQAChain } from 'langchain/chains';\nimport { VectorStoreQATool } from 'langchain/tools';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\nimport { NodeConnectionTypes } from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nexport class ToolVectorStore implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Vector Store Question Answer Tool',\n\t\tname: 'toolVectorStore',\n\t\ticon: 'fa:database',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1],\n\t\tdescription: 'Answer questions with a vector store',\n\t\tdefaults: {\n\t\t\tname: 'Answer questions with a vector store',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Other Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolvectorstore/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Vector Store',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiVectorStore,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Data Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. users_info',\n\t\t\t\tvalidateType: 'string-alphanumeric',\n\t\t\t\tdescription:\n\t\t\t\t\t'Name of the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question.',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description of Data',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: \"[Describe your data here, e.g. a user's name, email, etc.]\",\n\t\t\t\tdescription:\n\t\t\t\t\t'Describe the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Limit',\n\t\t\t\tname: 'topK',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 4,\n\t\t\t\tdescription: 'The maximum number of results to return',\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolVectorStore/ToolVectorStore.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { VectorStore } from '@langchain/core/vectorstores';\nimport { VectorDBQAChain } from 'langchain/chains';\nimport { VectorStoreQATool } from 'langchain/tools';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\nimport { NodeConnectionTypes } from 'n8n-workflow';\n\nimport { nodeNameToToolName } from '@utils/helpers';\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nexport class ToolVectorStore implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Vector Store Question Answer Tool',\n\t\tname: 'toolVectorStore',\n\t\ticon: 'fa:database',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Answer questions with a vector store',\n\t\tdefaults: {\n\t\t\tname: 'Answer questions with a vector store',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Tools'],\n\t\t\t\tTools: ['Other Tools'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolvectorstore/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Vector Store',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiVectorStore,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Data Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. users_info',\n\t\t\t\tvalidateType: 'string-alphanumeric',\n\t\t\t\tdescription:\n\t\t\t\t\t'Name of the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question.',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Description of Data',\n\t\t\t\tname: 'description',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: \"[Describe your data here, e.g. a user's name, email, etc.]\",\n\t\t\t\tdescription:\n\t\t\t\t\t'Describe the data in vector store. This will be used to fill this tool description: Useful for when you need to answer questions about [name]. Whenever you need information about [data description], you should ALWAYS use this. Input should be a fully formed question.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Limit',\n\t\t\t\tname: 'topK',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 4,\n\t\t\t\tdescription: 'The maximum number of results to return',\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst { typeVersion } = node;\n\t\tconst name =\n\t\t\ttypeVersion <= 1\n\t\t\t\t? (this.getNodeParameter('name', itemIndex) as string)\n\t\t\t\t: nodeNameToToolName(node);\n\t\tconst toolDescription = this.getNodeParameter('description', itemIndex) as string;\n\t\tconst topK = this.getNodeParameter('topK', itemIndex, 4) as number;\n\n\t\tconst vectorStore = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiVectorStore,\n\t\t\titemIndex,\n\t\t)) as VectorStore;\n\n\t\tconst llm = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t0,\n\t\t)) as BaseLanguageModel;\n\n\t\tconst description = VectorStoreQATool.getDescription(name, toolDescription);\n\t\tconst vectorStoreTool = new VectorStoreQATool(name, description, {\n\t\t\tllm,\n\t\t\tvectorStore,\n\t\t});\n\n\t\tvectorStoreTool.chain = VectorDBQAChain.fromLLM(llm, vectorStore, {\n\t\t\tk: topK,\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: logWrapper(vectorStoreTool, this),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAAgC;AAChC,mBAAkC;AAOlC,0BAAoC;AAEpC,qBAAmC;AACnC,wBAA2B;AAC3B,0BAA6C;AAEtC,MAAM,gBAAqC;AAAA,EAA3C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,GAAG,GAAG;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,OAAO;AAAA,UACZ,OAAO,CAAC,aAAa;AAAA,QACtB;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA;AAAA,MAEA,QAAQ;AAAA,QACP;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,MACD;AAAA;AAAA,MAEA,SAAS,CAAC,wCAAoB,MAAM;AAAA,MACpC,aAAa,CAAC,MAAM;AAAA,MACpB,YAAY;AAAA,YACX,kDAA6B,CAAC,wCAAoB,OAAO,CAAC;AAAA,QAC1D;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,UACb,cAAc;AAAA,UACd,aACC;AAAA,UACD,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,CAAC;AAAA,YACf;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,UACb,aACC;AAAA,UACD,aAAa;AAAA,YACZ,MAAM;AAAA,UACP;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,OACL,eAAe,IACX,KAAK,iBAAiB,QAAQ,SAAS,QACxC,mCAAmB,IAAI;AAC3B,UAAM,kBAAkB,KAAK,iBAAiB,eAAe,SAAS;AACtE,UAAM,OAAO,KAAK,iBAAiB,QAAQ,WAAW,CAAC;AAEvD,UAAM,cAAe,MAAM,KAAK;AAAA,MAC/B,wCAAoB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,MAAO,MAAM,KAAK;AAAA,MACvB,wCAAoB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,cAAc,+BAAkB,eAAe,MAAM,eAAe;AAC1E,UAAM,kBAAkB,IAAI,+BAAkB,MAAM,aAAa;AAAA,MAChE;AAAA,MACA;AAAA,IACD,CAAC;AAED,oBAAgB,QAAQ,8BAAgB,QAAQ,KAAK,aAAa;AAAA,MACjE,GAAG;AAAA,IACJ,CAAC;AAED,WAAO;AAAA,MACN,cAAU,8BAAW,iBAAiB,IAAI;AAAA,IAC3C;AAAA,EACD;AACD;","names":[]}
|
|
@@ -47,7 +47,7 @@ class ToolWorkflow extends import_n8n_workflow.VersionedNodeType {
|
|
|
47
47
|
]
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
-
defaultVersion: 2.
|
|
50
|
+
defaultVersion: 2.2
|
|
51
51
|
};
|
|
52
52
|
const nodeVersions = {
|
|
53
53
|
1: new import_ToolWorkflowV1.ToolWorkflowV1(baseDescription),
|
|
@@ -55,7 +55,8 @@ class ToolWorkflow extends import_n8n_workflow.VersionedNodeType {
|
|
|
55
55
|
1.2: new import_ToolWorkflowV1.ToolWorkflowV1(baseDescription),
|
|
56
56
|
1.3: new import_ToolWorkflowV1.ToolWorkflowV1(baseDescription),
|
|
57
57
|
2: new import_ToolWorkflowV2.ToolWorkflowV2(baseDescription),
|
|
58
|
-
2.1: new import_ToolWorkflowV2.ToolWorkflowV2(baseDescription)
|
|
58
|
+
2.1: new import_ToolWorkflowV2.ToolWorkflowV2(baseDescription),
|
|
59
|
+
2.2: new import_ToolWorkflowV2.ToolWorkflowV2(baseDescription)
|
|
59
60
|
};
|
|
60
61
|
super(nodeVersions, baseDescription);
|
|
61
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolWorkflow/ToolWorkflow.node.ts"],"sourcesContent":["import type { IVersionedNodeType, INodeTypeBaseDescription } from 'n8n-workflow';\nimport { VersionedNodeType } from 'n8n-workflow';\n\nimport { ToolWorkflowV1 } from './v1/ToolWorkflowV1.node';\nimport { ToolWorkflowV2 } from './v2/ToolWorkflowV2.node';\n\nexport class ToolWorkflow extends VersionedNodeType {\n\tconstructor() {\n\t\tconst baseDescription: INodeTypeBaseDescription = {\n\t\t\tdisplayName: 'Call n8n Sub-Workflow Tool',\n\t\t\tname: 'toolWorkflow',\n\t\t\ticon: 'fa:network-wired',\n\t\t\ticonColor: 'black',\n\t\t\tgroup: ['transform'],\n\t\t\tdescription:\n\t\t\t\t'Uses another n8n workflow as a tool. Allows packaging any n8n node(s) as a tool.',\n\t\t\tcodex: {\n\t\t\t\tcategories: ['AI'],\n\t\t\t\tsubcategories: {\n\t\t\t\t\tAI: ['Tools'],\n\t\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t\t},\n\t\t\t\tresources: {\n\t\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\tdefaultVersion: 2.
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolWorkflow/ToolWorkflow.node.ts"],"sourcesContent":["import type { IVersionedNodeType, INodeTypeBaseDescription } from 'n8n-workflow';\nimport { VersionedNodeType } from 'n8n-workflow';\n\nimport { ToolWorkflowV1 } from './v1/ToolWorkflowV1.node';\nimport { ToolWorkflowV2 } from './v2/ToolWorkflowV2.node';\n\nexport class ToolWorkflow extends VersionedNodeType {\n\tconstructor() {\n\t\tconst baseDescription: INodeTypeBaseDescription = {\n\t\t\tdisplayName: 'Call n8n Sub-Workflow Tool',\n\t\t\tname: 'toolWorkflow',\n\t\t\ticon: 'fa:network-wired',\n\t\t\ticonColor: 'black',\n\t\t\tgroup: ['transform'],\n\t\t\tdescription:\n\t\t\t\t'Uses another n8n workflow as a tool. Allows packaging any n8n node(s) as a tool.',\n\t\t\tcodex: {\n\t\t\t\tcategories: ['AI'],\n\t\t\t\tsubcategories: {\n\t\t\t\t\tAI: ['Tools'],\n\t\t\t\t\tTools: ['Recommended Tools'],\n\t\t\t\t},\n\t\t\t\tresources: {\n\t\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\tdefaultVersion: 2.2,\n\t\t};\n\n\t\tconst nodeVersions: IVersionedNodeType['nodeVersions'] = {\n\t\t\t1: new ToolWorkflowV1(baseDescription),\n\t\t\t1.1: new ToolWorkflowV1(baseDescription),\n\t\t\t1.2: new ToolWorkflowV1(baseDescription),\n\t\t\t1.3: new ToolWorkflowV1(baseDescription),\n\t\t\t2: new ToolWorkflowV2(baseDescription),\n\t\t\t2.1: new ToolWorkflowV2(baseDescription),\n\t\t\t2.2: new ToolWorkflowV2(baseDescription),\n\t\t};\n\t\tsuper(nodeVersions, baseDescription);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAkC;AAElC,4BAA+B;AAC/B,4BAA+B;AAExB,MAAM,qBAAqB,sCAAkB;AAAA,EACnD,cAAc;AACb,UAAM,kBAA4C;AAAA,MACjD,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,WAAW;AAAA,MACnB,aACC;AAAA,MACD,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,OAAO;AAAA,UACZ,OAAO,CAAC,mBAAmB;AAAA,QAC5B;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,gBAAgB;AAAA,IACjB;AAEA,UAAM,eAAmD;AAAA,MACxD,GAAG,IAAI,qCAAe,eAAe;AAAA,MACrC,KAAK,IAAI,qCAAe,eAAe;AAAA,MACvC,KAAK,IAAI,qCAAe,eAAe;AAAA,MACvC,KAAK,IAAI,qCAAe,eAAe;AAAA,MACvC,GAAG,IAAI,qCAAe,eAAe;AAAA,MACrC,KAAK,IAAI,qCAAe,eAAe;AAAA,MACvC,KAAK,IAAI,qCAAe,eAAe;AAAA,IACxC;AACA,UAAM,cAAc,eAAe;AAAA,EACpC;AACD;","names":[]}
|
|
@@ -21,6 +21,7 @@ __export(ToolWorkflowV2_node_exports, {
|
|
|
21
21
|
ToolWorkflowV2: () => ToolWorkflowV2
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(ToolWorkflowV2_node_exports);
|
|
24
|
+
var import_helpers = require("../../../../utils/helpers");
|
|
24
25
|
var import_methods = require("./methods");
|
|
25
26
|
var import_WorkflowToolService = require("./utils/WorkflowToolService");
|
|
26
27
|
var import_versionDescription = require("./versionDescription");
|
|
@@ -35,9 +36,11 @@ class ToolWorkflowV2 {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
async supplyData(itemIndex) {
|
|
38
|
-
const
|
|
39
|
+
const node = this.getNode();
|
|
40
|
+
const { typeVersion } = node;
|
|
41
|
+
const returnAllItems = typeVersion > 2;
|
|
39
42
|
const workflowToolService = new import_WorkflowToolService.WorkflowToolService(this, { returnAllItems });
|
|
40
|
-
const name = this.getNodeParameter("name", itemIndex);
|
|
43
|
+
const name = typeVersion <= 2.1 ? this.getNodeParameter("name", itemIndex) : (0, import_helpers.nodeNameToToolName)(node);
|
|
41
44
|
const description = this.getNodeParameter("description", itemIndex);
|
|
42
45
|
const tool = await workflowToolService.createTool({
|
|
43
46
|
name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.ts"],"sourcesContent":["import type {\n\tINodeTypeBaseDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { localResourceMapping } from './methods';\nimport { WorkflowToolService } from './utils/WorkflowToolService';\nimport { versionDescription } from './versionDescription';\n\nexport class ToolWorkflowV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\t...versionDescription,\n\t\t};\n\t}\n\n\tmethods = {\n\t\tlocalResourceMapping,\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.ts"],"sourcesContent":["import type {\n\tINodeTypeBaseDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { nodeNameToToolName } from '@utils/helpers';\n\nimport { localResourceMapping } from './methods';\nimport { WorkflowToolService } from './utils/WorkflowToolService';\nimport { versionDescription } from './versionDescription';\n\nexport class ToolWorkflowV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\t...versionDescription,\n\t\t};\n\t}\n\n\tmethods = {\n\t\tlocalResourceMapping,\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst { typeVersion } = node;\n\t\tconst returnAllItems = typeVersion > 2;\n\n\t\tconst workflowToolService = new WorkflowToolService(this, { returnAllItems });\n\t\tconst name =\n\t\t\ttypeVersion <= 2.1\n\t\t\t\t? (this.getNodeParameter('name', itemIndex) as string)\n\t\t\t\t: nodeNameToToolName(node);\n\t\tconst description = this.getNodeParameter('description', itemIndex) as string;\n\n\t\tconst tool = await workflowToolService.createTool({\n\t\t\tname,\n\t\t\tdescription,\n\t\t\titemIndex,\n\t\t});\n\n\t\treturn { response: tool };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,qBAAmC;AAEnC,qBAAqC;AACrC,iCAAoC;AACpC,gCAAmC;AAE5B,MAAM,eAAoC;AAAA,EAGhD,YAAY,iBAA2C;AAOvD,mBAAU;AAAA,MACT;AAAA,IACD;AARC,SAAK,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,EACD;AAAA,EAMA,MAAM,WAAuC,WAAwC;AACpF,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,iBAAiB,cAAc;AAErC,UAAM,sBAAsB,IAAI,+CAAoB,MAAM,EAAE,eAAe,CAAC;AAC5E,UAAM,OACL,eAAe,MACX,KAAK,iBAAiB,QAAQ,SAAS,QACxC,mCAAmB,IAAI;AAC3B,UAAM,cAAc,KAAK,iBAAiB,eAAe,SAAS;AAElE,UAAM,OAAO,MAAM,oBAAoB,WAAW;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,WAAO,EAAE,UAAU,KAAK;AAAA,EACzB;AACD;","names":[]}
|
|
@@ -31,7 +31,7 @@ const versionDescription = {
|
|
|
31
31
|
defaults: {
|
|
32
32
|
name: "Call n8n Workflow Tool"
|
|
33
33
|
},
|
|
34
|
-
version: [2, 2.1],
|
|
34
|
+
version: [2, 2.1, 2.2],
|
|
35
35
|
inputs: [],
|
|
36
36
|
outputs: [import_n8n_workflow.NodeConnectionTypes.AiTool],
|
|
37
37
|
outputNames: ["Tool"],
|
|
@@ -50,7 +50,12 @@ const versionDescription = {
|
|
|
50
50
|
default: "",
|
|
51
51
|
placeholder: "e.g. My_Color_Tool",
|
|
52
52
|
validateType: "string-alphanumeric",
|
|
53
|
-
description: "The name of the function to be called, could contain letters, numbers, and underscores only"
|
|
53
|
+
description: "The name of the function to be called, could contain letters, numbers, and underscores only",
|
|
54
|
+
displayOptions: {
|
|
55
|
+
show: {
|
|
56
|
+
"@version": [{ _cnd: { lte: 2.1 } }]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
54
59
|
},
|
|
55
60
|
{
|
|
56
61
|
displayName: "Description",
|