@n8n/n8n-nodes-langchain 1.112.1 → 1.113.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/nodes/mcp/McpClientTool/McpClientTool.node.js +13 -18
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/descriptions.js +49 -0
- package/dist/nodes/mcp/McpClientTool/descriptions.js.map +1 -0
- package/dist/nodes/tools/ToolCalculator/ToolCalculator.node.js +24 -1
- package/dist/nodes/tools/ToolCalculator/ToolCalculator.node.js.map +1 -1
- package/dist/nodes/tools/ToolCode/ToolCode.node.js +122 -102
- package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
- package/dist/nodes/tools/ToolSearXng/ToolSearXng.node.js +29 -10
- package/dist/nodes/tools/ToolSearXng/ToolSearXng.node.js.map +1 -1
- package/dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js +22 -3
- package/dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js.map +1 -1
- package/dist/nodes/tools/ToolThink/ToolThink.node.js +32 -11
- package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +42 -21
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
- package/dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js +24 -3
- package/dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js.map +1 -1
- package/dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js +18 -0
- package/dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +30 -13
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +27 -19
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/constants.js +2 -2
- package/dist/nodes/trigger/ChatTrigger/constants.js.map +1 -1
- package/dist/types/nodes.json +2 -2
- package/package.json +8 -8
|
@@ -24,6 +24,7 @@ module.exports = __toCommonJS(McpClientTool_node_exports);
|
|
|
24
24
|
var import_logWrapper = require("../../../utils/logWrapper");
|
|
25
25
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
26
26
|
var import_n8n_workflow = require("n8n-workflow");
|
|
27
|
+
var import_descriptions = require("./descriptions");
|
|
27
28
|
var import_loadOptions = require("./loadOptions");
|
|
28
29
|
var import_utils = require("./utils");
|
|
29
30
|
class McpClientTool {
|
|
@@ -36,7 +37,7 @@ class McpClientTool {
|
|
|
36
37
|
dark: "file:../mcp.dark.svg"
|
|
37
38
|
},
|
|
38
39
|
group: ["output"],
|
|
39
|
-
version: [1, 1.1],
|
|
40
|
+
version: [1, 1.1, 1.2],
|
|
40
41
|
description: "Connect tools from an MCP Server",
|
|
41
42
|
defaults: {
|
|
42
43
|
name: "MCP Client"
|
|
@@ -108,28 +109,22 @@ class McpClientTool {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
},
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
name: "Server Sent Events (Deprecated)",
|
|
118
|
-
value: "sse"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
name: "HTTP Streamable",
|
|
122
|
-
value: "httpStreamable"
|
|
112
|
+
(0, import_descriptions.transportSelect)({
|
|
113
|
+
defaultOption: "sse",
|
|
114
|
+
displayOptions: {
|
|
115
|
+
show: {
|
|
116
|
+
"@version": [1.1]
|
|
123
117
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
(0, import_descriptions.transportSelect)({
|
|
121
|
+
defaultOption: "httpStreamable",
|
|
127
122
|
displayOptions: {
|
|
128
123
|
show: {
|
|
129
|
-
"@version": [{ _cnd: { gte: 1.
|
|
124
|
+
"@version": [{ _cnd: { gte: 1.2 } }]
|
|
130
125
|
}
|
|
131
126
|
}
|
|
132
|
-
},
|
|
127
|
+
}),
|
|
133
128
|
{
|
|
134
129
|
displayName: "Authentication",
|
|
135
130
|
name: "authentication",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\nimport {\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getTools } from './loadOptions';\nimport type { McpServerTransport, McpAuthenticationOption, McpToolIncludeMode } from './types';\nimport {\n\tconnectMcpClient,\n\tcreateCallTool,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tgetSelectedTools,\n\tMcpToolkit,\n\tmcpToolToDynamicTool,\n} from './utils';\n\nexport class McpClientTool implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Client Tool',\n\t\tname: 'mcpClientTool',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Connect tools from an MCP Server',\n\t\tdefaults: {\n\t\t\tname: 'MCP Client',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Model Context Protocol', 'Tools'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Client'],\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.toolmcp/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' }],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBearerAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'httpHeaderAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\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: 'SSE Endpoint',\n\t\t\t\tname: 'sseEndpoint',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'SSE Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/sse',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\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: 'Endpoint',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\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: 'Server Transport',\n\t\t\t\tname: 'serverTransport',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Server Sent Events (Deprecated)',\n\t\t\t\t\t\tvalue: 'sse',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'HTTP Streamable',\n\t\t\t\t\t\tvalue: 'httpStreamable',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'sse',\n\t\t\t\tdescription: 'The transport used by your endpoint',\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: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'include',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription: 'How to select the tools you want to be exposed to the AI Agent',\n\t\t\t\tdefault: 'all',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All',\n\t\t\t\t\t\tvalue: 'all',\n\t\t\t\t\t\tdescription: 'Also include all unchanged fields from the input',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Selected',\n\t\t\t\t\t\tvalue: 'selected',\n\t\t\t\t\t\tdescription: 'Also include the tools listed in the parameter \"Tools to Include\"',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All Except',\n\t\t\t\t\t\tvalue: 'except',\n\t\t\t\t\t\tdescription: 'Exclude the tools listed in the parameter \"Tools to Exclude\"',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'includeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t\tloadOptionsDependsOn: ['sseEndpoint'],\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['selected'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Exclude',\n\t\t\t\tname: 'excludeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['except'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tgetTools,\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst authentication = this.getNodeParameter(\n\t\t\t'authentication',\n\t\t\titemIndex,\n\t\t) as McpAuthenticationOption;\n\t\tconst node = this.getNode();\n\t\tconst timeout = this.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\n\t\tlet serverTransport: McpServerTransport;\n\t\tlet endpointUrl: string;\n\t\tif (node.typeVersion === 1) {\n\t\t\tserverTransport = 'sse';\n\t\t\tendpointUrl = this.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t\t} else {\n\t\t\tserverTransport = this.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\t\tendpointUrl = this.getNodeParameter('endpointUrl', itemIndex) as string;\n\t\t}\n\n\t\tconst { headers } = await getAuthHeaders(this, authentication);\n\t\tconst client = await connectMcpClient({\n\t\t\tserverTransport,\n\t\t\tendpointUrl,\n\t\t\theaders,\n\t\t\tname: node.type,\n\t\t\tversion: node.typeVersion,\n\t\t});\n\n\t\tconst setError = (message: string, description?: string): SupplyData => {\n\t\t\tconst error = new NodeOperationError(node, message, { itemIndex, description });\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tif (!client.ok) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', {\n\t\t\t\terror: client.error,\n\t\t\t});\n\n\t\t\tswitch (client.error.type) {\n\t\t\t\tcase 'invalid_url':\n\t\t\t\t\treturn setError('Could not connect to your MCP server. The provided URL is invalid.');\n\t\t\t\tcase 'connection':\n\t\t\t\tdefault:\n\t\t\t\t\treturn setError('Could not connect to your MCP server');\n\t\t\t}\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tconst mode = this.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\t\tconst includeTools = this.getNodeParameter('includeTools', itemIndex, []) as string[];\n\t\tconst excludeTools = this.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\t\tconst allTools = await getAllTools(client.result);\n\t\tconst mcpTools = getSelectedTools({\n\t\t\ttools: allTools,\n\t\t\tmode,\n\t\t\tincludeTools,\n\t\t\texcludeTools,\n\t\t});\n\n\t\tif (!mcpTools.length) {\n\t\t\treturn setError(\n\t\t\t\t'MCP Server returned no tools',\n\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t);\n\t\t}\n\n\t\tconst tools = mcpTools.map((tool) =>\n\t\t\tlogWrapper(\n\t\t\t\tmcpToolToDynamicTool(\n\t\t\t\t\ttool,\n\t\t\t\t\tcreateCallTool(tool.name, client.result, timeout, (errorMessage) => {\n\t\t\t\t\t\tconst error = new NodeOperationError(node, errorMessage, { itemIndex });\n\t\t\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tthis,\n\t\t\t),\n\t\t);\n\n\t\tthis.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);\n\n\t\tconst toolkit = new McpToolkit(tools);\n\n\t\treturn { response: toolkit, closeFunction: async () => await client.result.close() };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA2B;AAC3B,0BAA6C;AAC7C,0BAOO;AAEP,yBAAyB;AAEzB,mBAQO;AAEA,MAAM,cAAmC;AAAA,EAAzC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,MACP;AAAA,MACA,OAAO,CAAC,QAAQ;AAAA,MAChB,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,0BAA0B,OAAO;AAAA,QACvC;AAAA,QACA,OAAO,CAAC,0BAA0B,YAAY;AAAA,QAC9C,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,EAAE,MAAM,wCAAoB,QAAQ,aAAa,QAAQ,CAAC;AAAA,MACpE,aAAa;AAAA,QACZ;AAAA;AAAA,UAEC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,YAAY;AAAA,YAC9B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,YAAY;AAAA,YAC9B;AAAA,UACD;AAAA,QACD;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,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,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,aAAa;AAAA,UACb,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UACT,aAAa;AAAA,UACb,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,cAAc,YAAY;AAAA,YAC5C;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aACC;AAAA,UACD,aAAa;AAAA,YACZ,mBAAmB;AAAA,YACnB,sBAAsB,CAAC,aAAa;AAAA,UACrC;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,UAAU;AAAA,YACrB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aACC;AAAA,UACD,aAAa;AAAA,YACZ,mBAAmB;AAAA,UACpB;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,QAAQ;AAAA,YACnB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,gBACZ,UAAU;AAAA,cACX;AAAA,cACA,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,mBAAU;AAAA,MACT,aAAa;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,iBAAiB,KAAK;AAAA,MAC3B;AAAA,MACA;AAAA,IACD;AACA,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,UAAU,KAAK,iBAAiB,mBAAmB,WAAW,GAAK;AAEzE,QAAI;AACJ,QAAI;AACJ,QAAI,KAAK,gBAAgB,GAAG;AAC3B,wBAAkB;AAClB,oBAAc,KAAK,iBAAiB,eAAe,SAAS;AAAA,IAC7D,OAAO;AACN,wBAAkB,KAAK,iBAAiB,mBAAmB,SAAS;AACpE,oBAAc,KAAK,iBAAiB,eAAe,SAAS;AAAA,IAC7D;AAEA,UAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,UAAM,SAAS,UAAM,+BAAiB;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,IACf,CAAC;AAED,UAAM,WAAW,CAAC,SAAiB,gBAAqC;AACvE,YAAM,QAAQ,IAAI,uCAAmB,MAAM,SAAS,EAAE,WAAW,YAAY,CAAC;AAC9E,WAAK,cAAc,wCAAoB,QAAQ,WAAW,KAAK;AAC/D,YAAM;AAAA,IACP;AAEA,QAAI,CAAC,OAAO,IAAI;AACf,WAAK,OAAO,MAAM,kDAAkD;AAAA,QACnE,OAAO,OAAO;AAAA,MACf,CAAC;AAED,cAAQ,OAAO,MAAM,MAAM;AAAA,QAC1B,KAAK;AACJ,iBAAO,SAAS,oEAAoE;AAAA,QACrF,KAAK;AAAA,QACL;AACC,iBAAO,SAAS,sCAAsC;AAAA,MACxD;AAAA,IACD;AAEA,SAAK,OAAO,MAAM,qDAAqD;AAEvE,UAAM,OAAO,KAAK,iBAAiB,WAAW,SAAS;AACvD,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,CAAC,CAAC;AACxE,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,CAAC,CAAC;AAExE,UAAM,WAAW,UAAM,0BAAY,OAAO,MAAM;AAChD,UAAM,eAAW,+BAAiB;AAAA,MACjC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,QAAI,CAAC,SAAS,QAAQ;AACrB,aAAO;AAAA,QACN;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,QAAQ,SAAS;AAAA,MAAI,CAAC,aAC3B;AAAA,YACC;AAAA,UACC;AAAA,cACA,6BAAe,KAAK,MAAM,OAAO,QAAQ,SAAS,CAAC,iBAAiB;AACnE,kBAAM,QAAQ,IAAI,uCAAmB,MAAM,cAAc,EAAE,UAAU,CAAC;AACtE,iBAAK,KAAK,cAAc,wCAAoB,QAAQ,WAAW,KAAK;AACpE,iBAAK,OAAO,MAAM,wBAAwB,KAAK,IAAI,uBAAuB,EAAE,MAAM,CAAC;AAAA,UACpF,CAAC;AAAA,QACF;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,SAAK,OAAO,MAAM,+CAA+C,MAAM,MAAM,QAAQ;AAErF,UAAM,UAAU,IAAI,wBAAW,KAAK;AAEpC,WAAO,EAAE,UAAU,SAAS,eAAe,YAAY,MAAM,OAAO,OAAO,MAAM,EAAE;AAAA,EACpF;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\nimport {\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { transportSelect } from './descriptions';\nimport { getTools } from './loadOptions';\nimport type { McpServerTransport, McpAuthenticationOption, McpToolIncludeMode } from './types';\nimport {\n\tconnectMcpClient,\n\tcreateCallTool,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tgetSelectedTools,\n\tMcpToolkit,\n\tmcpToolToDynamicTool,\n} from './utils';\n\nexport class McpClientTool implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Client Tool',\n\t\tname: 'mcpClientTool',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Connect tools from an MCP Server',\n\t\tdefaults: {\n\t\t\tname: 'MCP Client',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Model Context Protocol', 'Tools'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Client'],\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.toolmcp/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' }],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBearerAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'httpHeaderAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\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: 'SSE Endpoint',\n\t\t\t\tname: 'sseEndpoint',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'SSE Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/sse',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\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: 'Endpoint',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\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\ttransportSelect({\n\t\t\t\tdefaultOption: 'sse',\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\ttransportSelect({\n\t\t\t\tdefaultOption: 'httpStreamable',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'include',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription: 'How to select the tools you want to be exposed to the AI Agent',\n\t\t\t\tdefault: 'all',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All',\n\t\t\t\t\t\tvalue: 'all',\n\t\t\t\t\t\tdescription: 'Also include all unchanged fields from the input',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Selected',\n\t\t\t\t\t\tvalue: 'selected',\n\t\t\t\t\t\tdescription: 'Also include the tools listed in the parameter \"Tools to Include\"',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All Except',\n\t\t\t\t\t\tvalue: 'except',\n\t\t\t\t\t\tdescription: 'Exclude the tools listed in the parameter \"Tools to Exclude\"',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'includeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t\tloadOptionsDependsOn: ['sseEndpoint'],\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['selected'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Exclude',\n\t\t\t\tname: 'excludeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['except'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tgetTools,\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst authentication = this.getNodeParameter(\n\t\t\t'authentication',\n\t\t\titemIndex,\n\t\t) as McpAuthenticationOption;\n\t\tconst node = this.getNode();\n\t\tconst timeout = this.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\n\t\tlet serverTransport: McpServerTransport;\n\t\tlet endpointUrl: string;\n\t\tif (node.typeVersion === 1) {\n\t\t\tserverTransport = 'sse';\n\t\t\tendpointUrl = this.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t\t} else {\n\t\t\tserverTransport = this.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\t\tendpointUrl = this.getNodeParameter('endpointUrl', itemIndex) as string;\n\t\t}\n\n\t\tconst { headers } = await getAuthHeaders(this, authentication);\n\t\tconst client = await connectMcpClient({\n\t\t\tserverTransport,\n\t\t\tendpointUrl,\n\t\t\theaders,\n\t\t\tname: node.type,\n\t\t\tversion: node.typeVersion,\n\t\t});\n\n\t\tconst setError = (message: string, description?: string): SupplyData => {\n\t\t\tconst error = new NodeOperationError(node, message, { itemIndex, description });\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tif (!client.ok) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', {\n\t\t\t\terror: client.error,\n\t\t\t});\n\n\t\t\tswitch (client.error.type) {\n\t\t\t\tcase 'invalid_url':\n\t\t\t\t\treturn setError('Could not connect to your MCP server. The provided URL is invalid.');\n\t\t\t\tcase 'connection':\n\t\t\t\tdefault:\n\t\t\t\t\treturn setError('Could not connect to your MCP server');\n\t\t\t}\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tconst mode = this.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\t\tconst includeTools = this.getNodeParameter('includeTools', itemIndex, []) as string[];\n\t\tconst excludeTools = this.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\t\tconst allTools = await getAllTools(client.result);\n\t\tconst mcpTools = getSelectedTools({\n\t\t\ttools: allTools,\n\t\t\tmode,\n\t\t\tincludeTools,\n\t\t\texcludeTools,\n\t\t});\n\n\t\tif (!mcpTools.length) {\n\t\t\treturn setError(\n\t\t\t\t'MCP Server returned no tools',\n\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t);\n\t\t}\n\n\t\tconst tools = mcpTools.map((tool) =>\n\t\t\tlogWrapper(\n\t\t\t\tmcpToolToDynamicTool(\n\t\t\t\t\ttool,\n\t\t\t\t\tcreateCallTool(tool.name, client.result, timeout, (errorMessage) => {\n\t\t\t\t\t\tconst error = new NodeOperationError(node, errorMessage, { itemIndex });\n\t\t\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tthis,\n\t\t\t),\n\t\t);\n\n\t\tthis.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);\n\n\t\tconst toolkit = new McpToolkit(tools);\n\n\t\treturn { response: toolkit, closeFunction: async () => await client.result.close() };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA2B;AAC3B,0BAA6C;AAC7C,0BAOO;AAEP,0BAAgC;AAChC,yBAAyB;AAEzB,mBAQO;AAEA,MAAM,cAAmC;AAAA,EAAzC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,MACP;AAAA,MACA,OAAO,CAAC,QAAQ;AAAA,MAChB,SAAS,CAAC,GAAG,KAAK,GAAG;AAAA,MACrB,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,0BAA0B,OAAO;AAAA,QACvC;AAAA,QACA,OAAO,CAAC,0BAA0B,YAAY;AAAA,QAC9C,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,EAAE,MAAM,wCAAoB,QAAQ,aAAa,QAAQ,CAAC;AAAA,MACpE,aAAa;AAAA,QACZ;AAAA;AAAA,UAEC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,YAAY;AAAA,YAC9B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,YAAY;AAAA,YAC9B;AAAA,UACD;AAAA,QACD;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,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,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,aAAa;AAAA,UACb,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,YACA,qCAAgB;AAAA,UACf,eAAe;AAAA,UACf,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,GAAG;AAAA,YACjB;AAAA,UACD;AAAA,QACD,CAAC;AAAA,YACD,qCAAgB;AAAA,UACf,eAAe;AAAA,UACf,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD,CAAC;AAAA,QACD;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,cAAc,YAAY;AAAA,YAC5C;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aACC;AAAA,UACD,aAAa;AAAA,YACZ,mBAAmB;AAAA,YACnB,sBAAsB,CAAC,aAAa;AAAA,UACrC;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,UAAU;AAAA,YACrB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aACC;AAAA,UACD,aAAa;AAAA,YACZ,mBAAmB;AAAA,UACpB;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,QAAQ;AAAA,YACnB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,gBACZ,UAAU;AAAA,cACX;AAAA,cACA,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,mBAAU;AAAA,MACT,aAAa;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,iBAAiB,KAAK;AAAA,MAC3B;AAAA,MACA;AAAA,IACD;AACA,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,UAAU,KAAK,iBAAiB,mBAAmB,WAAW,GAAK;AAEzE,QAAI;AACJ,QAAI;AACJ,QAAI,KAAK,gBAAgB,GAAG;AAC3B,wBAAkB;AAClB,oBAAc,KAAK,iBAAiB,eAAe,SAAS;AAAA,IAC7D,OAAO;AACN,wBAAkB,KAAK,iBAAiB,mBAAmB,SAAS;AACpE,oBAAc,KAAK,iBAAiB,eAAe,SAAS;AAAA,IAC7D;AAEA,UAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,UAAM,SAAS,UAAM,+BAAiB;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,IACf,CAAC;AAED,UAAM,WAAW,CAAC,SAAiB,gBAAqC;AACvE,YAAM,QAAQ,IAAI,uCAAmB,MAAM,SAAS,EAAE,WAAW,YAAY,CAAC;AAC9E,WAAK,cAAc,wCAAoB,QAAQ,WAAW,KAAK;AAC/D,YAAM;AAAA,IACP;AAEA,QAAI,CAAC,OAAO,IAAI;AACf,WAAK,OAAO,MAAM,kDAAkD;AAAA,QACnE,OAAO,OAAO;AAAA,MACf,CAAC;AAED,cAAQ,OAAO,MAAM,MAAM;AAAA,QAC1B,KAAK;AACJ,iBAAO,SAAS,oEAAoE;AAAA,QACrF,KAAK;AAAA,QACL;AACC,iBAAO,SAAS,sCAAsC;AAAA,MACxD;AAAA,IACD;AAEA,SAAK,OAAO,MAAM,qDAAqD;AAEvE,UAAM,OAAO,KAAK,iBAAiB,WAAW,SAAS;AACvD,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,CAAC,CAAC;AACxE,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,CAAC,CAAC;AAExE,UAAM,WAAW,UAAM,0BAAY,OAAO,MAAM;AAChD,UAAM,eAAW,+BAAiB;AAAA,MACjC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,QAAI,CAAC,SAAS,QAAQ;AACrB,aAAO;AAAA,QACN;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,QAAQ,SAAS;AAAA,MAAI,CAAC,aAC3B;AAAA,YACC;AAAA,UACC;AAAA,cACA,6BAAe,KAAK,MAAM,OAAO,QAAQ,SAAS,CAAC,iBAAiB;AACnE,kBAAM,QAAQ,IAAI,uCAAmB,MAAM,cAAc,EAAE,UAAU,CAAC;AACtE,iBAAK,KAAK,cAAc,wCAAoB,QAAQ,WAAW,KAAK;AACpE,iBAAK,OAAO,MAAM,wBAAwB,KAAK,IAAI,uBAAuB,EAAE,MAAM,CAAC;AAAA,UACpF,CAAC;AAAA,QACF;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,SAAK,OAAO,MAAM,+CAA+C,MAAM,MAAM,QAAQ;AAErF,UAAM,UAAU,IAAI,wBAAW,KAAK;AAEpC,WAAO,EAAE,UAAU,SAAS,eAAe,YAAY,MAAM,OAAO,OAAO,MAAM,EAAE;AAAA,EACpF;AACD;","names":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 descriptions_exports = {};
|
|
20
|
+
__export(descriptions_exports, {
|
|
21
|
+
transportSelect: () => transportSelect
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(descriptions_exports);
|
|
24
|
+
const transportSelect = ({
|
|
25
|
+
defaultOption,
|
|
26
|
+
displayOptions
|
|
27
|
+
}) => ({
|
|
28
|
+
displayName: "Server Transport",
|
|
29
|
+
name: "serverTransport",
|
|
30
|
+
type: "options",
|
|
31
|
+
options: [
|
|
32
|
+
{
|
|
33
|
+
name: "HTTP Streamable",
|
|
34
|
+
value: "httpStreamable"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Server Sent Events (Deprecated)",
|
|
38
|
+
value: "sse"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
default: defaultOption,
|
|
42
|
+
description: "The transport used by your endpoint",
|
|
43
|
+
displayOptions
|
|
44
|
+
});
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
transportSelect
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=descriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/mcp/McpClientTool/descriptions.ts"],"sourcesContent":["import type { IDisplayOptions, INodeProperties } from 'n8n-workflow';\n\nexport const transportSelect = ({\n\tdefaultOption,\n\tdisplayOptions,\n}: {\n\tdefaultOption: 'sse' | 'httpStreamable';\n\tdisplayOptions: IDisplayOptions;\n}): INodeProperties => ({\n\tdisplayName: 'Server Transport',\n\tname: 'serverTransport',\n\ttype: 'options',\n\toptions: [\n\t\t{\n\t\t\tname: 'HTTP Streamable',\n\t\t\tvalue: 'httpStreamable',\n\t\t},\n\t\t{\n\t\t\tname: 'Server Sent Events (Deprecated)',\n\t\t\tvalue: 'sse',\n\t\t},\n\t],\n\tdefault: defaultOption,\n\tdescription: 'The transport used by your endpoint',\n\tdisplayOptions,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,kBAAkB,CAAC;AAAA,EAC/B;AAAA,EACA;AACD,OAGwB;AAAA,EACvB,aAAa;AAAA,EACb,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,IACR;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,IACR;AAAA,IACA;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EACA,SAAS;AAAA,EACT,aAAa;AAAA,EACb;AACD;","names":[]}
|
|
@@ -25,6 +25,11 @@ var import_calculator = require("@langchain/community/tools/calculator");
|
|
|
25
25
|
var import_n8n_workflow = require("n8n-workflow");
|
|
26
26
|
var import_logWrapper = require("../../../utils/logWrapper");
|
|
27
27
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
28
|
+
function getTool(ctx) {
|
|
29
|
+
const calculator = new import_calculator.Calculator();
|
|
30
|
+
calculator.name = ctx.getNode().name;
|
|
31
|
+
return calculator;
|
|
32
|
+
}
|
|
28
33
|
class ToolCalculator {
|
|
29
34
|
constructor() {
|
|
30
35
|
this.description = {
|
|
@@ -60,9 +65,27 @@ class ToolCalculator {
|
|
|
60
65
|
}
|
|
61
66
|
async supplyData() {
|
|
62
67
|
return {
|
|
63
|
-
response: (0, import_logWrapper.logWrapper)(
|
|
68
|
+
response: (0, import_logWrapper.logWrapper)(getTool(this), this)
|
|
64
69
|
};
|
|
65
70
|
}
|
|
71
|
+
async execute() {
|
|
72
|
+
const calculator = getTool(this);
|
|
73
|
+
const input = this.getInputData();
|
|
74
|
+
const response = [];
|
|
75
|
+
for (let i = 0; i < input.length; i++) {
|
|
76
|
+
const inputItem = input[i];
|
|
77
|
+
const result = await calculator.invoke(inputItem.json);
|
|
78
|
+
response.push({
|
|
79
|
+
json: {
|
|
80
|
+
response: result
|
|
81
|
+
},
|
|
82
|
+
pairedItem: {
|
|
83
|
+
item: i
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return [response];
|
|
88
|
+
}
|
|
66
89
|
}
|
|
67
90
|
// Annotate the CommonJS export names for ESM import in node:
|
|
68
91
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolCalculator/ToolCalculator.node.ts"],"sourcesContent":["import { Calculator } from '@langchain/community/tools/calculator';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nexport class ToolCalculator implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Calculator',\n\t\tname: 'toolCalculator',\n\t\ticon: 'fa:calculator',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Make it easier for AI agents to perform arithmetic',\n\t\tdefaults: {\n\t\t\tname: 'Calculator',\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.toolcalculator/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [],\n\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [getConnectionHintNoticeField([NodeConnectionTypes.AiAgent])],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {\n\t\treturn {\n\t\t\tresponse: logWrapper(
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/tools/ToolCalculator/ToolCalculator.node.ts"],"sourcesContent":["import { Calculator } from '@langchain/community/tools/calculator';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nfunction getTool(ctx: ISupplyDataFunctions | IExecuteFunctions): Calculator {\n\tconst calculator = new Calculator();\n\tcalculator.name = ctx.getNode().name;\n\treturn calculator;\n}\n\nexport class ToolCalculator implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Calculator',\n\t\tname: 'toolCalculator',\n\t\ticon: 'fa:calculator',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Make it easier for AI agents to perform arithmetic',\n\t\tdefaults: {\n\t\t\tname: 'Calculator',\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.toolcalculator/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [],\n\n\t\toutputs: [NodeConnectionTypes.AiTool],\n\t\toutputNames: ['Tool'],\n\t\tproperties: [getConnectionHintNoticeField([NodeConnectionTypes.AiAgent])],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {\n\t\treturn {\n\t\t\tresponse: logWrapper(getTool(this), this),\n\t\t};\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst calculator = getTool(this);\n\t\tconst input = this.getInputData();\n\t\tconst response: INodeExecutionData[] = [];\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst inputItem = input[i];\n\t\t\tconst result = await calculator.invoke(inputItem.json);\n\t\t\tresponse.push({\n\t\t\t\tjson: {\n\t\t\t\t\tresponse: result,\n\t\t\t\t},\n\t\t\t\tpairedItem: {\n\t\t\t\t\titem: i,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\treturn [response];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA2B;AAC3B,0BAQO;AAEP,wBAA2B;AAC3B,0BAA6C;AAE7C,SAAS,QAAQ,KAA2D;AAC3E,QAAM,aAAa,IAAI,6BAAW;AAClC,aAAW,OAAO,IAAI,QAAQ,EAAE;AAChC,SAAO;AACR;AAEO,MAAM,eAAoC;AAAA,EAA1C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,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,MAEA,QAAQ,CAAC;AAAA,MAET,SAAS,CAAC,wCAAoB,MAAM;AAAA,MACpC,aAAa,CAAC,MAAM;AAAA,MACpB,YAAY,KAAC,kDAA6B,CAAC,wCAAoB,OAAO,CAAC,CAAC;AAAA,IACzE;AAAA;AAAA,EAEA,MAAM,aAA4D;AACjE,WAAO;AAAA,MACN,cAAU,8BAAW,QAAQ,IAAI,GAAG,IAAI;AAAA,IACzC;AAAA,EACD;AAAA,EAEA,MAAM,UAAkE;AACvE,UAAM,aAAa,QAAQ,IAAI;AAC/B,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,WAAiC,CAAC;AACxC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,SAAS,MAAM,WAAW,OAAO,UAAU,IAAI;AACrD,eAAS,KAAK;AAAA,QACb,MAAM;AAAA,UACL,UAAU;AAAA,QACX;AAAA,QACA,YAAY;AAAA,UACX,MAAM;AAAA,QACP;AAAA,MACD,CAAC;AAAA,IACF;AAEA,WAAO,CAAC,QAAQ;AAAA,EACjB;AACD;","names":[]}
|
|
@@ -42,6 +42,110 @@ const jsonSchemaExampleNotice = (0, import_descriptions.buildJsonSchemaExampleNo
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
const jsonSchemaField = (0, import_descriptions.buildInputSchemaField)({ showExtraProps: { specifyInputSchema: [true] } });
|
|
45
|
+
function getTool(ctx, itemIndex, log = true) {
|
|
46
|
+
const node = ctx.getNode();
|
|
47
|
+
const workflowMode = ctx.getMode();
|
|
48
|
+
const runnersConfig = import_di.Container.get(import_config.TaskRunnersConfig);
|
|
49
|
+
const isRunnerEnabled = runnersConfig.enabled;
|
|
50
|
+
const { typeVersion } = node;
|
|
51
|
+
const name = typeVersion <= 1.1 ? ctx.getNodeParameter("name", itemIndex) : (0, import_n8n_workflow.nodeNameToToolName)(node);
|
|
52
|
+
const description = ctx.getNodeParameter("description", itemIndex);
|
|
53
|
+
const useSchema = ctx.getNodeParameter("specifyInputSchema", itemIndex);
|
|
54
|
+
const language = ctx.getNodeParameter("language", itemIndex);
|
|
55
|
+
let code = "";
|
|
56
|
+
if (language === "javaScript") {
|
|
57
|
+
code = ctx.getNodeParameter("jsCode", itemIndex);
|
|
58
|
+
} else {
|
|
59
|
+
code = ctx.getNodeParameter("pythonCode", itemIndex);
|
|
60
|
+
}
|
|
61
|
+
const getSandbox = (query, index = 0) => {
|
|
62
|
+
const context = import_Sandbox.getSandboxContext.call(ctx, index);
|
|
63
|
+
context.query = query;
|
|
64
|
+
let sandbox;
|
|
65
|
+
if (language === "javaScript") {
|
|
66
|
+
sandbox = new import_JavaScriptSandbox.JavaScriptSandbox(context, code, ctx.helpers);
|
|
67
|
+
} else {
|
|
68
|
+
sandbox = new import_PythonSandbox.PythonSandbox(context, code, ctx.helpers);
|
|
69
|
+
}
|
|
70
|
+
sandbox.on(
|
|
71
|
+
"output",
|
|
72
|
+
workflowMode === "manual" ? ctx.sendMessageToUI.bind(ctx) : (...args) => console.log(`[Workflow "${ctx.getWorkflow().id}"][Node "${node.name}"]`, ...args)
|
|
73
|
+
);
|
|
74
|
+
return sandbox;
|
|
75
|
+
};
|
|
76
|
+
const runFunction = async (query) => {
|
|
77
|
+
if (language === "javaScript" && isRunnerEnabled) {
|
|
78
|
+
const sandbox = new import_JsTaskRunnerSandbox.JsTaskRunnerSandbox(
|
|
79
|
+
code,
|
|
80
|
+
"runOnceForAllItems",
|
|
81
|
+
workflowMode,
|
|
82
|
+
ctx,
|
|
83
|
+
void 0,
|
|
84
|
+
{
|
|
85
|
+
query
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
const executionData = await sandbox.runCodeForTool();
|
|
89
|
+
return executionData;
|
|
90
|
+
} else {
|
|
91
|
+
const sandbox = getSandbox(query, itemIndex);
|
|
92
|
+
return await sandbox.runCode();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const toolHandler = async (query) => {
|
|
96
|
+
const { index } = log ? ctx.addInputData(import_n8n_workflow.NodeConnectionTypes.AiTool, [[{ json: { query } }]]) : { index: 0 };
|
|
97
|
+
let response = "";
|
|
98
|
+
let executionError;
|
|
99
|
+
try {
|
|
100
|
+
response = await runFunction(query);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
executionError = new import_n8n_workflow.NodeOperationError(ctx.getNode(), error);
|
|
103
|
+
response = `There was an error: "${executionError.message}"`;
|
|
104
|
+
}
|
|
105
|
+
if (typeof response === "number") {
|
|
106
|
+
response = response.toString();
|
|
107
|
+
}
|
|
108
|
+
if (typeof response !== "string") {
|
|
109
|
+
executionError = new import_n8n_workflow.NodeOperationError(ctx.getNode(), "Wrong output type returned", {
|
|
110
|
+
description: `The response property should be a string, but it is an ${typeof response}`
|
|
111
|
+
});
|
|
112
|
+
response = `There was an error: "${executionError.message}"`;
|
|
113
|
+
}
|
|
114
|
+
if (executionError && log) {
|
|
115
|
+
void ctx.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, index, executionError);
|
|
116
|
+
} else if (log) {
|
|
117
|
+
void ctx.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, index, [[{ json: { response } }]]);
|
|
118
|
+
}
|
|
119
|
+
return response;
|
|
120
|
+
};
|
|
121
|
+
const commonToolOptions = {
|
|
122
|
+
name,
|
|
123
|
+
description,
|
|
124
|
+
func: toolHandler
|
|
125
|
+
};
|
|
126
|
+
let tool = void 0;
|
|
127
|
+
if (useSchema) {
|
|
128
|
+
try {
|
|
129
|
+
const jsonExample = ctx.getNodeParameter("jsonSchemaExample", itemIndex, "");
|
|
130
|
+
const inputSchema = ctx.getNodeParameter("inputSchema", itemIndex, "");
|
|
131
|
+
const schemaType = ctx.getNodeParameter("schemaType", itemIndex);
|
|
132
|
+
const jsonSchema = schemaType === "fromJson" ? (0, import_schemaParsing.generateSchemaFromExample)(jsonExample, ctx.getNode().typeVersion >= 1.3) : (0, import_n8n_workflow.jsonParse)(inputSchema);
|
|
133
|
+
const zodSchema = (0, import_schemaParsing.convertJsonSchemaToZod)(jsonSchema);
|
|
134
|
+
tool = new import_tools.DynamicStructuredTool({
|
|
135
|
+
schema: zodSchema,
|
|
136
|
+
...commonToolOptions
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw new import_n8n_workflow.NodeOperationError(
|
|
140
|
+
ctx.getNode(),
|
|
141
|
+
"Error during parsing of JSON Schema. \n " + error
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
tool = new import_tools.DynamicTool(commonToolOptions);
|
|
146
|
+
}
|
|
147
|
+
return tool;
|
|
148
|
+
}
|
|
45
149
|
class ToolCode {
|
|
46
150
|
constructor() {
|
|
47
151
|
this.description = {
|
|
@@ -189,111 +293,27 @@ class ToolCode {
|
|
|
189
293
|
};
|
|
190
294
|
}
|
|
191
295
|
async supplyData(itemIndex) {
|
|
192
|
-
const node = this.getNode();
|
|
193
|
-
const workflowMode = this.getMode();
|
|
194
|
-
const runnersConfig = import_di.Container.get(import_config.TaskRunnersConfig);
|
|
195
|
-
const isRunnerEnabled = runnersConfig.enabled;
|
|
196
|
-
const { typeVersion } = node;
|
|
197
|
-
const name = typeVersion <= 1.1 ? this.getNodeParameter("name", itemIndex) : (0, import_n8n_workflow.nodeNameToToolName)(node);
|
|
198
|
-
const description = this.getNodeParameter("description", itemIndex);
|
|
199
|
-
const useSchema = this.getNodeParameter("specifyInputSchema", itemIndex);
|
|
200
|
-
const language = this.getNodeParameter("language", itemIndex);
|
|
201
|
-
let code = "";
|
|
202
|
-
if (language === "javaScript") {
|
|
203
|
-
code = this.getNodeParameter("jsCode", itemIndex);
|
|
204
|
-
} else {
|
|
205
|
-
code = this.getNodeParameter("pythonCode", itemIndex);
|
|
206
|
-
}
|
|
207
|
-
const getSandbox = (query, index = 0) => {
|
|
208
|
-
const context = import_Sandbox.getSandboxContext.call(this, index);
|
|
209
|
-
context.query = query;
|
|
210
|
-
let sandbox;
|
|
211
|
-
if (language === "javaScript") {
|
|
212
|
-
sandbox = new import_JavaScriptSandbox.JavaScriptSandbox(context, code, this.helpers);
|
|
213
|
-
} else {
|
|
214
|
-
sandbox = new import_PythonSandbox.PythonSandbox(context, code, this.helpers);
|
|
215
|
-
}
|
|
216
|
-
sandbox.on(
|
|
217
|
-
"output",
|
|
218
|
-
workflowMode === "manual" ? this.sendMessageToUI.bind(this) : (...args) => console.log(`[Workflow "${this.getWorkflow().id}"][Node "${node.name}"]`, ...args)
|
|
219
|
-
);
|
|
220
|
-
return sandbox;
|
|
221
|
-
};
|
|
222
|
-
const runFunction = async (query) => {
|
|
223
|
-
if (language === "javaScript" && isRunnerEnabled) {
|
|
224
|
-
const sandbox = new import_JsTaskRunnerSandbox.JsTaskRunnerSandbox(
|
|
225
|
-
code,
|
|
226
|
-
"runOnceForAllItems",
|
|
227
|
-
workflowMode,
|
|
228
|
-
this,
|
|
229
|
-
void 0,
|
|
230
|
-
{
|
|
231
|
-
query
|
|
232
|
-
}
|
|
233
|
-
);
|
|
234
|
-
const executionData = await sandbox.runCodeForTool();
|
|
235
|
-
return executionData;
|
|
236
|
-
} else {
|
|
237
|
-
const sandbox = getSandbox(query, itemIndex);
|
|
238
|
-
return await sandbox.runCode();
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
const toolHandler = async (query) => {
|
|
242
|
-
const { index } = this.addInputData(import_n8n_workflow.NodeConnectionTypes.AiTool, [[{ json: { query } }]]);
|
|
243
|
-
let response = "";
|
|
244
|
-
let executionError;
|
|
245
|
-
try {
|
|
246
|
-
response = await runFunction(query);
|
|
247
|
-
} catch (error) {
|
|
248
|
-
executionError = new import_n8n_workflow.NodeOperationError(this.getNode(), error);
|
|
249
|
-
response = `There was an error: "${executionError.message}"`;
|
|
250
|
-
}
|
|
251
|
-
if (typeof response === "number") {
|
|
252
|
-
response = response.toString();
|
|
253
|
-
}
|
|
254
|
-
if (typeof response !== "string") {
|
|
255
|
-
executionError = new import_n8n_workflow.NodeOperationError(this.getNode(), "Wrong output type returned", {
|
|
256
|
-
description: `The response property should be a string, but it is an ${typeof response}`
|
|
257
|
-
});
|
|
258
|
-
response = `There was an error: "${executionError.message}"`;
|
|
259
|
-
}
|
|
260
|
-
if (executionError) {
|
|
261
|
-
void this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, index, executionError);
|
|
262
|
-
} else {
|
|
263
|
-
void this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, index, [[{ json: { response } }]]);
|
|
264
|
-
}
|
|
265
|
-
return response;
|
|
266
|
-
};
|
|
267
|
-
const commonToolOptions = {
|
|
268
|
-
name,
|
|
269
|
-
description,
|
|
270
|
-
func: toolHandler
|
|
271
|
-
};
|
|
272
|
-
let tool = void 0;
|
|
273
|
-
if (useSchema) {
|
|
274
|
-
try {
|
|
275
|
-
const jsonExample = this.getNodeParameter("jsonSchemaExample", itemIndex, "");
|
|
276
|
-
const inputSchema = this.getNodeParameter("inputSchema", itemIndex, "");
|
|
277
|
-
const schemaType = this.getNodeParameter("schemaType", itemIndex);
|
|
278
|
-
const jsonSchema = schemaType === "fromJson" ? (0, import_schemaParsing.generateSchemaFromExample)(jsonExample, this.getNode().typeVersion >= 1.3) : (0, import_n8n_workflow.jsonParse)(inputSchema);
|
|
279
|
-
const zodSchema = (0, import_schemaParsing.convertJsonSchemaToZod)(jsonSchema);
|
|
280
|
-
tool = new import_tools.DynamicStructuredTool({
|
|
281
|
-
schema: zodSchema,
|
|
282
|
-
...commonToolOptions
|
|
283
|
-
});
|
|
284
|
-
} catch (error) {
|
|
285
|
-
throw new import_n8n_workflow.NodeOperationError(
|
|
286
|
-
this.getNode(),
|
|
287
|
-
"Error during parsing of JSON Schema. \n " + error
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
} else {
|
|
291
|
-
tool = new import_tools.DynamicTool(commonToolOptions);
|
|
292
|
-
}
|
|
293
296
|
return {
|
|
294
|
-
response:
|
|
297
|
+
response: getTool(this, itemIndex)
|
|
295
298
|
};
|
|
296
299
|
}
|
|
300
|
+
async execute() {
|
|
301
|
+
const result = [];
|
|
302
|
+
const input = this.getInputData();
|
|
303
|
+
for (let i = 0; i < input.length; i++) {
|
|
304
|
+
const item = input[i];
|
|
305
|
+
const tool = getTool(this, i, false);
|
|
306
|
+
result.push({
|
|
307
|
+
json: {
|
|
308
|
+
response: await tool.invoke(item.json)
|
|
309
|
+
},
|
|
310
|
+
pairedItem: {
|
|
311
|
+
item: i
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return [result];
|
|
316
|
+
}
|
|
297
317
|
}
|
|
298
318
|
// Annotate the CommonJS export names for ESM import in node:
|
|
299
319
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/tools/ToolCode/ToolCode.node.ts"],"sourcesContent":["import { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { TaskRunnersConfig } from '@n8n/config';\nimport { Container } from '@n8n/di';\nimport type { JSONSchema7 } from 'json-schema';\nimport { JavaScriptSandbox } from 'n8n-nodes-base/dist/nodes/Code/JavaScriptSandbox';\nimport { JsTaskRunnerSandbox } from 'n8n-nodes-base/dist/nodes/Code/JsTaskRunnerSandbox';\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\tExecutionError,\n\tIDataObject,\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\n\nimport {\n\tjsonParse,\n\tNodeConnectionTypes,\n\tnodeNameToToolName,\n\tNodeOperationError,\n} from 'n8n-workflow';\nimport {\n\tbuildInputSchemaField,\n\tbuildJsonSchemaExampleField,\n\tbuildJsonSchemaExampleNotice,\n\tschemaTypeField,\n} from '@utils/descriptions';\nimport { convertJsonSchemaToZod, generateSchemaFromExample } from '@utils/schemaParsing';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport type { DynamicZodObject } from '../../../types/zod.types';\n\nconst jsonSchemaExampleField = buildJsonSchemaExampleField({\n\tshowExtraProps: { specifyInputSchema: [true] },\n});\n\nconst jsonSchemaExampleNotice = buildJsonSchemaExampleNotice({\n\tshowExtraProps: {\n\t\tspecifyInputSchema: [true],\n\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t},\n});\n\nconst jsonSchemaField = buildInputSchemaField({ showExtraProps: { specifyInputSchema: [true] } });\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, 1.3],\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\n\t\tinputs: [],\n\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\tjsonSchemaExampleField,\n\t\t\tjsonSchemaExampleNotice,\n\t\t\tjsonSchemaField,\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 runnersConfig = Container.get(TaskRunnersConfig);\n\t\tconst isRunnerEnabled = runnersConfig.enabled;\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\t// @deprecated - TODO: Remove this after a new python runner is implemented\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<unknown> => {\n\t\t\tif (language === 'javaScript' && isRunnerEnabled) {\n\t\t\t\tconst sandbox = new JsTaskRunnerSandbox(\n\t\t\t\t\tcode,\n\t\t\t\t\t'runOnceForAllItems',\n\t\t\t\t\tworkflowMode,\n\t\t\t\t\tthis,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tquery,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst executionData = await sandbox.runCodeForTool();\n\t\t\t\treturn executionData;\n\t\t\t} else {\n\t\t\t\t// use old vm2-based sandbox for python or when without runner enabled\n\t\t\t\tconst sandbox = getSandbox(query, itemIndex);\n\t\t\t\treturn await sandbox.runCode<string>();\n\t\t\t}\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: any = '';\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\n\t\t\t\tconst jsonSchema =\n\t\t\t\t\tschemaType === 'fromJson'\n\t\t\t\t\t\t? generateSchemaFromExample(jsonExample, this.getNode().typeVersion >= 1.3)\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":["import { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { TaskRunnersConfig } from '@n8n/config';\nimport { Container } from '@n8n/di';\nimport type { JSONSchema7 } from 'json-schema';\nimport { JavaScriptSandbox } from 'n8n-nodes-base/dist/nodes/Code/JavaScriptSandbox';\nimport { JsTaskRunnerSandbox } from 'n8n-nodes-base/dist/nodes/Code/JsTaskRunnerSandbox';\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\tExecutionError,\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\nimport {\n\tjsonParse,\n\tNodeConnectionTypes,\n\tnodeNameToToolName,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport {\n\tbuildInputSchemaField,\n\tbuildJsonSchemaExampleField,\n\tbuildJsonSchemaExampleNotice,\n\tschemaTypeField,\n} from '@utils/descriptions';\nimport { convertJsonSchemaToZod, generateSchemaFromExample } from '@utils/schemaParsing';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport type { DynamicZodObject } from '../../../types/zod.types';\n\nconst jsonSchemaExampleField = buildJsonSchemaExampleField({\n\tshowExtraProps: { specifyInputSchema: [true] },\n});\n\nconst jsonSchemaExampleNotice = buildJsonSchemaExampleNotice({\n\tshowExtraProps: {\n\t\tspecifyInputSchema: [true],\n\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t},\n});\n\nconst jsonSchemaField = buildInputSchemaField({ showExtraProps: { specifyInputSchema: [true] } });\n\nfunction getTool(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\titemIndex: number,\n\tlog: boolean = true,\n) {\n\tconst node = ctx.getNode();\n\tconst workflowMode = ctx.getMode();\n\n\tconst runnersConfig = Container.get(TaskRunnersConfig);\n\tconst isRunnerEnabled = runnersConfig.enabled;\n\n\tconst { typeVersion } = node;\n\tconst name =\n\t\ttypeVersion <= 1.1\n\t\t\t? (ctx.getNodeParameter('name', itemIndex) as string)\n\t\t\t: nodeNameToToolName(node);\n\n\tconst description = ctx.getNodeParameter('description', itemIndex) as string;\n\n\tconst useSchema = ctx.getNodeParameter('specifyInputSchema', itemIndex) as boolean;\n\n\tconst language = ctx.getNodeParameter('language', itemIndex) as string;\n\tlet code = '';\n\tif (language === 'javaScript') {\n\t\tcode = ctx.getNodeParameter('jsCode', itemIndex) as string;\n\t} else {\n\t\tcode = ctx.getNodeParameter('pythonCode', itemIndex) as string;\n\t}\n\n\t// @deprecated - TODO: Remove this after a new python runner is implemented\n\tconst getSandbox = (query: string | IDataObject, index = 0) => {\n\t\tconst context = getSandboxContext.call(ctx, index);\n\t\tcontext.query = query;\n\n\t\tlet sandbox: Sandbox;\n\t\tif (language === 'javaScript') {\n\t\t\tsandbox = new JavaScriptSandbox(context, code, ctx.helpers);\n\t\t} else {\n\t\t\tsandbox = new PythonSandbox(context, code, ctx.helpers);\n\t\t}\n\n\t\tsandbox.on(\n\t\t\t'output',\n\t\t\tworkflowMode === 'manual'\n\t\t\t\t? ctx.sendMessageToUI.bind(ctx)\n\t\t\t\t: (...args: unknown[]) =>\n\t\t\t\t\t\tconsole.log(`[Workflow \"${ctx.getWorkflow().id}\"][Node \"${node.name}\"]`, ...args),\n\t\t);\n\t\treturn sandbox;\n\t};\n\n\tconst runFunction = async (query: string | IDataObject): Promise<unknown> => {\n\t\tif (language === 'javaScript' && isRunnerEnabled) {\n\t\t\tconst sandbox = new JsTaskRunnerSandbox(\n\t\t\t\tcode,\n\t\t\t\t'runOnceForAllItems',\n\t\t\t\tworkflowMode,\n\t\t\t\tctx,\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tquery,\n\t\t\t\t},\n\t\t\t);\n\t\t\tconst executionData = await sandbox.runCodeForTool();\n\t\t\treturn executionData;\n\t\t} else {\n\t\t\t// use old vm2-based sandbox for python or when without runner enabled\n\t\t\tconst sandbox = getSandbox(query, itemIndex);\n\t\t\treturn await sandbox.runCode<string>();\n\t\t}\n\t};\n\n\tconst toolHandler = async (query: string | IDataObject): Promise<string> => {\n\t\tconst { index } = log\n\t\t\t? ctx.addInputData(NodeConnectionTypes.AiTool, [[{ json: { query } }]])\n\t\t\t: { index: 0 };\n\n\t\tlet response: any = '';\n\t\tlet executionError: ExecutionError | undefined;\n\t\ttry {\n\t\t\tresponse = await runFunction(query);\n\t\t} catch (error: unknown) {\n\t\t\texecutionError = new NodeOperationError(ctx.getNode(), error as ExecutionError);\n\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t}\n\n\t\tif (typeof response === 'number') {\n\t\t\tresponse = (response as number).toString();\n\t\t}\n\n\t\tif (typeof response !== 'string') {\n\t\t\t// TODO: Do some more testing. Issues here should actually fail the workflow\n\t\t\texecutionError = new NodeOperationError(ctx.getNode(), 'Wrong output type returned', {\n\t\t\t\tdescription: `The response property should be a string, but it is an ${typeof response}`,\n\t\t\t});\n\t\t\tresponse = `There was an error: \"${executionError.message}\"`;\n\t\t}\n\n\t\tif (executionError && log) {\n\t\t\tvoid ctx.addOutputData(NodeConnectionTypes.AiTool, index, executionError);\n\t\t} else if (log) {\n\t\t\tvoid ctx.addOutputData(NodeConnectionTypes.AiTool, index, [[{ json: { response } }]]);\n\t\t}\n\n\t\treturn response;\n\t};\n\n\tconst commonToolOptions = {\n\t\tname,\n\t\tdescription,\n\t\tfunc: toolHandler,\n\t};\n\n\tlet tool: DynamicTool | DynamicStructuredTool | undefined = undefined;\n\n\tif (useSchema) {\n\t\ttry {\n\t\t\t// We initialize these even though one of them will always be empty\n\t\t\t// it makes it easier to navigate the ternary operator\n\t\t\tconst jsonExample = ctx.getNodeParameter('jsonSchemaExample', itemIndex, '') as string;\n\t\t\tconst inputSchema = ctx.getNodeParameter('inputSchema', itemIndex, '') as string;\n\n\t\t\tconst schemaType = ctx.getNodeParameter('schemaType', itemIndex) as 'fromJson' | 'manual';\n\n\t\t\tconst jsonSchema =\n\t\t\t\tschemaType === 'fromJson'\n\t\t\t\t\t? generateSchemaFromExample(jsonExample, ctx.getNode().typeVersion >= 1.3)\n\t\t\t\t\t: jsonParse<JSONSchema7>(inputSchema);\n\n\t\t\tconst zodSchema = convertJsonSchemaToZod<DynamicZodObject>(jsonSchema);\n\n\t\t\ttool = new DynamicStructuredTool({\n\t\t\t\tschema: zodSchema,\n\t\t\t\t...commonToolOptions,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tctx.getNode(),\n\t\t\t\t'Error during parsing of JSON Schema. \\n ' + error,\n\t\t\t);\n\t\t}\n\t} else {\n\t\ttool = new DynamicTool(commonToolOptions);\n\t}\n\n\treturn tool;\n}\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, 1.3],\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\n\t\tinputs: [],\n\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\tjsonSchemaExampleField,\n\t\t\tjsonSchemaExampleNotice,\n\t\t\tjsonSchemaField,\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\treturn {\n\t\t\tresponse: getTool(this, itemIndex),\n\t\t};\n\t}\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst result: INodeExecutionData[] = [];\n\t\tconst input = this.getInputData();\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst item = input[i];\n\t\t\tconst tool = getTool(this, i, false);\n\t\t\tresult.push({\n\t\t\t\tjson: {\n\t\t\t\t\tresponse: await tool.invoke(item.json),\n\t\t\t\t},\n\t\t\t\tpairedItem: {\n\t\t\t\t\titem: i,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\treturn [result];\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -25,6 +25,17 @@ var import_searxng_search = require("@langchain/community/tools/searxng_search")
|
|
|
25
25
|
var import_n8n_workflow = require("n8n-workflow");
|
|
26
26
|
var import_logWrapper = require("../../../utils/logWrapper");
|
|
27
27
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
28
|
+
async function getTool(ctx, itemIndex) {
|
|
29
|
+
const credentials = await ctx.getCredentials("searXngApi");
|
|
30
|
+
const options = ctx.getNodeParameter("options", itemIndex);
|
|
31
|
+
return new import_searxng_search.SearxngSearch({
|
|
32
|
+
apiBase: credentials.apiUrl,
|
|
33
|
+
headers: {
|
|
34
|
+
Accept: "application/json"
|
|
35
|
+
},
|
|
36
|
+
params: options
|
|
37
|
+
});
|
|
38
|
+
}
|
|
28
39
|
class ToolSearXng {
|
|
29
40
|
constructor() {
|
|
30
41
|
this.description = {
|
|
@@ -115,19 +126,27 @@ class ToolSearXng {
|
|
|
115
126
|
};
|
|
116
127
|
}
|
|
117
128
|
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
129
|
return {
|
|
128
|
-
response: (0, import_logWrapper.logWrapper)(
|
|
130
|
+
response: (0, import_logWrapper.logWrapper)(await getTool(this, itemIndex), this)
|
|
129
131
|
};
|
|
130
132
|
}
|
|
133
|
+
async execute() {
|
|
134
|
+
const result = [];
|
|
135
|
+
const input = this.getInputData();
|
|
136
|
+
for (let i = 0; i < input.length; i++) {
|
|
137
|
+
const item = input[i];
|
|
138
|
+
const tool = await getTool(this, i);
|
|
139
|
+
result.push({
|
|
140
|
+
json: {
|
|
141
|
+
response: await tool.invoke(item.json)
|
|
142
|
+
},
|
|
143
|
+
pairedItem: {
|
|
144
|
+
item: i
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return [result];
|
|
149
|
+
}
|
|
131
150
|
}
|
|
132
151
|
// Annotate the CommonJS export names for ESM import in node:
|
|
133
152
|
0 && (module.exports = {
|