@n8n/n8n-nodes-langchain 2.2.2 → 2.3.1
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/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js +4 -2
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +14 -1
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/nodes/tools/ToolCode/ToolCode.node.js +23 -32
- package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/constants.js +1 -11
- package/dist/nodes/trigger/ChatTrigger/constants.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreWeaviate/VectorStoreWeaviate.node.js +121 -11
- package/dist/nodes/vector_store/VectorStoreWeaviate/VectorStoreWeaviate.node.js.map +1 -1
- package/dist/types/nodes.json +2 -2
- package/dist/utils/agent-execution/buildSteps.js +2 -2
- package/dist/utils/agent-execution/buildSteps.js.map +1 -1
- package/dist/utils/agent-execution/memoryManagement.js +81 -6
- package/dist/utils/agent-execution/memoryManagement.js.map +1 -1
- package/dist/utils/output_parsers/N8nStructuredOutputParser.js +16 -1
- package/dist/utils/output_parsers/N8nStructuredOutputParser.js.map +1 -1
- package/package.json +11 -11
|
@@ -55,7 +55,8 @@ async function runAgent(ctx, executor, itemContext, model, memory, response) {
|
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
if (memory && input && result?.output) {
|
|
58
|
-
|
|
58
|
+
const previousCount = response?.metadata?.previousRequests?.length;
|
|
59
|
+
await (0, import_agent_execution.saveToMemory)(input, result.output, memory, steps, previousCount);
|
|
59
60
|
}
|
|
60
61
|
if (options.returnIntermediateSteps && steps.length > 0) {
|
|
61
62
|
result.intermediateSteps = steps;
|
|
@@ -69,7 +70,8 @@ async function runAgent(ctx, executor, itemContext, model, memory, response) {
|
|
|
69
70
|
});
|
|
70
71
|
if ("returnValues" in modelResponse) {
|
|
71
72
|
if (memory && input && modelResponse.returnValues.output) {
|
|
72
|
-
|
|
73
|
+
const previousCount = response?.metadata?.previousRequests?.length;
|
|
74
|
+
await (0, import_agent_execution.saveToMemory)(input, modelResponse.returnValues.output, memory, steps, previousCount);
|
|
73
75
|
}
|
|
74
76
|
const result = { ...modelResponse.returnValues };
|
|
75
77
|
if (options.returnIntermediateSteps && steps.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport {\n\tloadMemory,\n\tprocessEventStream,\n\tcreateEngineRequests,\n\tsaveToMemory,\n} from '@utils/agent-execution';\n\nimport { SYSTEM_MESSAGE } from '../../prompt';\nimport type { AgentResult, RequestResponseMetadata } from '../types';\nimport { buildResponseMetadata } from './buildResponseMetadata';\nimport type { ItemContext } from './prepareItemContext';\n\ntype RunAgentResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Runs the agent for a single item, choosing between streaming or non-streaming execution.\n * Handles both regular execution and execution after tool calls.\n *\n * @param ctx - The execution context\n * @param executor - The agent runnable sequence\n * @param itemContext - Context for the current item\n * @param model - The chat model for token counting\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns AgentResult or engine request with tool calls\n */\nexport async function runAgent(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\texecutor: AgentRunnableSequence,\n\titemContext: ItemContext,\n\tmodel: BaseChatModel,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<RunAgentResult> {\n\tconst { itemIndex, input, steps, tools, options } = itemContext;\n\n\tconst invokeParams = {\n\t\tsteps,\n\t\tinput,\n\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\tformatting_instructions:\n\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t};\n\tconst executeOptions = { signal: ctx.getExecutionCancelSignal() };\n\n\t// Check if streaming is actually available\n\tconst isStreamingAvailable = 'isStreaming' in ctx ? ctx.isStreaming?.() : undefined;\n\n\tif (\n\t\t'isStreaming' in ctx &&\n\t\toptions.enableStreaming &&\n\t\tisStreamingAvailable &&\n\t\tctx.getNode().typeVersion >= 2.1\n\t) {\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\t\tconst eventStream = executor.streamEvents(\n\t\t\t{\n\t\t\t\t...invokeParams,\n\t\t\t\tchat_history: chatHistory,\n\t\t\t},\n\t\t\t{\n\t\t\t\tversion: 'v2',\n\t\t\t\t...executeOptions,\n\t\t\t},\n\t\t);\n\n\t\tconst result = await processEventStream(ctx, eventStream, itemIndex);\n\n\t\t// If result contains tool calls, build the request object like the normal flow\n\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t\t};\n\t\t}\n\t\t// Save conversation to memory including any tool call context\n\t\tif (memory && input && result?.output) {\n\t\t\tawait saveToMemory(input, result.output, memory, steps);\n\t\t}\n\n\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\tresult.intermediateSteps = steps;\n\t\t}\n\n\t\treturn result;\n\t} else {\n\t\t// Handle regular execution\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\n\t\tconst modelResponse = await executor.invoke({\n\t\t\t...invokeParams,\n\t\t\tchat_history: chatHistory,\n\t\t});\n\n\t\tif ('returnValues' in modelResponse) {\n\t\t\t// Save conversation to memory including any tool call context\n\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\tawait saveToMemory(input, modelResponse.returnValues.output, memory, steps);\n\t\t\t}\n\t\t\t// Include intermediate steps if requested\n\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// If response contains tool calls, we need to return this in the right format\n\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\treturn {\n\t\t\tactions,\n\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,6BAKO;AAEP,oBAA+B;AAE/B,mCAAsC;AAgBtC,eAAsB,SACrB,KACA,UACA,aACA,OACA,QACA,UAC0B;AAC1B,QAAM,EAAE,WAAW,OAAO,OAAO,OAAO,QAAQ,IAAI;AAEpD,QAAM,eAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ,iBAAiB;AAAA,IACzC,yBACC;AAAA,EACF;AACA,QAAM,iBAAiB,EAAE,QAAQ,IAAI,yBAAyB,EAAE;AAGhE,QAAM,uBAAuB,iBAAiB,MAAM,IAAI,cAAc,IAAI;AAE1E,MACC,iBAAiB,OACjB,QAAQ,mBACR,wBACA,IAAI,QAAQ,EAAE,eAAe,KAC5B;AACD,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAC/E,UAAM,cAAc,SAAS;AAAA,MAC5B;AAAA,QACC,GAAG;AAAA,QACH,cAAc;AAAA,MACf;AAAA,MACA;AAAA,QACC,SAAS;AAAA,QACT,GAAG;AAAA,MACJ;AAAA,IACD;AAEA,UAAM,SAAS,UAAM,2CAAmB,KAAK,aAAa,SAAS;AAGnE,QAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;AACpD,YAAM,UAAU,UAAM,6CAAqB,OAAO,WAAW,WAAW,KAAK;AAE7E,aAAO;AAAA,QACN;AAAA,QACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,MACpD;AAAA,IACD;AAEA,QAAI,UAAU,SAAS,QAAQ,QAAQ;AACtC,gBAAM,qCAAa,OAAO,OAAO,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport {\n\tloadMemory,\n\tprocessEventStream,\n\tcreateEngineRequests,\n\tsaveToMemory,\n} from '@utils/agent-execution';\n\nimport { SYSTEM_MESSAGE } from '../../prompt';\nimport type { AgentResult, RequestResponseMetadata } from '../types';\nimport { buildResponseMetadata } from './buildResponseMetadata';\nimport type { ItemContext } from './prepareItemContext';\n\ntype RunAgentResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Runs the agent for a single item, choosing between streaming or non-streaming execution.\n * Handles both regular execution and execution after tool calls.\n *\n * @param ctx - The execution context\n * @param executor - The agent runnable sequence\n * @param itemContext - Context for the current item\n * @param model - The chat model for token counting\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns AgentResult or engine request with tool calls\n */\nexport async function runAgent(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\texecutor: AgentRunnableSequence,\n\titemContext: ItemContext,\n\tmodel: BaseChatModel,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<RunAgentResult> {\n\tconst { itemIndex, input, steps, tools, options } = itemContext;\n\n\tconst invokeParams = {\n\t\tsteps,\n\t\tinput,\n\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\tformatting_instructions:\n\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t};\n\tconst executeOptions = { signal: ctx.getExecutionCancelSignal() };\n\n\t// Check if streaming is actually available\n\tconst isStreamingAvailable = 'isStreaming' in ctx ? ctx.isStreaming?.() : undefined;\n\n\tif (\n\t\t'isStreaming' in ctx &&\n\t\toptions.enableStreaming &&\n\t\tisStreamingAvailable &&\n\t\tctx.getNode().typeVersion >= 2.1\n\t) {\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\t\tconst eventStream = executor.streamEvents(\n\t\t\t{\n\t\t\t\t...invokeParams,\n\t\t\t\tchat_history: chatHistory,\n\t\t\t},\n\t\t\t{\n\t\t\t\tversion: 'v2',\n\t\t\t\t...executeOptions,\n\t\t\t},\n\t\t);\n\n\t\tconst result = await processEventStream(ctx, eventStream, itemIndex);\n\n\t\t// If result contains tool calls, build the request object like the normal flow\n\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t\t};\n\t\t}\n\t\t// Save conversation to memory including any tool call context\n\t\tif (memory && input && result?.output) {\n\t\t\tconst previousCount = response?.metadata?.previousRequests?.length;\n\t\t\tawait saveToMemory(input, result.output, memory, steps, previousCount);\n\t\t}\n\n\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\tresult.intermediateSteps = steps;\n\t\t}\n\n\t\treturn result;\n\t} else {\n\t\t// Handle regular execution\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\n\t\tconst modelResponse = await executor.invoke({\n\t\t\t...invokeParams,\n\t\t\tchat_history: chatHistory,\n\t\t});\n\n\t\tif ('returnValues' in modelResponse) {\n\t\t\t// Save conversation to memory including any tool call context\n\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\tconst previousCount = response?.metadata?.previousRequests?.length;\n\t\t\t\tawait saveToMemory(input, modelResponse.returnValues.output, memory, steps, previousCount);\n\t\t\t}\n\t\t\t// Include intermediate steps if requested\n\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// If response contains tool calls, we need to return this in the right format\n\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\treturn {\n\t\t\tactions,\n\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,6BAKO;AAEP,oBAA+B;AAE/B,mCAAsC;AAgBtC,eAAsB,SACrB,KACA,UACA,aACA,OACA,QACA,UAC0B;AAC1B,QAAM,EAAE,WAAW,OAAO,OAAO,OAAO,QAAQ,IAAI;AAEpD,QAAM,eAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ,iBAAiB;AAAA,IACzC,yBACC;AAAA,EACF;AACA,QAAM,iBAAiB,EAAE,QAAQ,IAAI,yBAAyB,EAAE;AAGhE,QAAM,uBAAuB,iBAAiB,MAAM,IAAI,cAAc,IAAI;AAE1E,MACC,iBAAiB,OACjB,QAAQ,mBACR,wBACA,IAAI,QAAQ,EAAE,eAAe,KAC5B;AACD,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAC/E,UAAM,cAAc,SAAS;AAAA,MAC5B;AAAA,QACC,GAAG;AAAA,QACH,cAAc;AAAA,MACf;AAAA,MACA;AAAA,QACC,SAAS;AAAA,QACT,GAAG;AAAA,MACJ;AAAA,IACD;AAEA,UAAM,SAAS,UAAM,2CAAmB,KAAK,aAAa,SAAS;AAGnE,QAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;AACpD,YAAM,UAAU,UAAM,6CAAqB,OAAO,WAAW,WAAW,KAAK;AAE7E,aAAO;AAAA,QACN;AAAA,QACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,MACpD;AAAA,IACD;AAEA,QAAI,UAAU,SAAS,QAAQ,QAAQ;AACtC,YAAM,gBAAgB,UAAU,UAAU,kBAAkB;AAC5D,gBAAM,qCAAa,OAAO,OAAO,QAAQ,QAAQ,OAAO,aAAa;AAAA,IACtE;AAEA,QAAI,QAAQ,2BAA2B,MAAM,SAAS,GAAG;AACxD,aAAO,oBAAoB;AAAA,IAC5B;AAEA,WAAO;AAAA,EACR,OAAO;AAEN,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAE/E,UAAM,gBAAgB,MAAM,SAAS,OAAO;AAAA,MAC3C,GAAG;AAAA,MACH,cAAc;AAAA,IACf,CAAC;AAED,QAAI,kBAAkB,eAAe;AAEpC,UAAI,UAAU,SAAS,cAAc,aAAa,QAAQ;AACzD,cAAM,gBAAgB,UAAU,UAAU,kBAAkB;AAC5D,kBAAM,qCAAa,OAAO,cAAc,aAAa,QAAQ,QAAQ,OAAO,aAAa;AAAA,MAC1F;AAEA,YAAM,SAAS,EAAE,GAAG,cAAc,aAAa;AAC/C,UAAI,QAAQ,2BAA2B,MAAM,SAAS,GAAG;AACxD,eAAO,oBAAoB;AAAA,MAC5B;AACA,aAAO;AAAA,IACR;AAGA,UAAM,UAAU,UAAM,6CAAqB,eAAe,WAAW,KAAK;AAE1E,WAAO;AAAA,MACN;AAAA,MACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,IACpD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var McpClientTool_node_exports = {};
|
|
20
30
|
__export(McpClientTool_node_exports, {
|
|
@@ -29,6 +39,7 @@ var import_loadOptions = require("./loadOptions");
|
|
|
29
39
|
var import_utils = require("./utils");
|
|
30
40
|
var import_descriptions = require("../shared/descriptions");
|
|
31
41
|
var import_utils2 = require("../shared/utils");
|
|
42
|
+
var import_pick = __toESM(require("lodash/pick"));
|
|
32
43
|
function getNodeConfig(ctx, itemIndex) {
|
|
33
44
|
const node = ctx.getNode();
|
|
34
45
|
const authentication = ctx.getNodeParameter(
|
|
@@ -374,9 +385,11 @@ class McpClientTool {
|
|
|
374
385
|
const toolName = item.json.tool;
|
|
375
386
|
if (toolName === tool.name) {
|
|
376
387
|
const { tool: _, ...toolArguments } = item.json;
|
|
388
|
+
const schema = tool.inputSchema;
|
|
389
|
+
const sanitizedToolArguments = schema.additionalProperties === false ? (0, import_pick.default)(toolArguments, Object.keys(schema.properties ?? {})) : toolArguments;
|
|
377
390
|
const params = {
|
|
378
391
|
name: tool.name,
|
|
379
|
-
arguments:
|
|
392
|
+
arguments: sanitizedToolArguments
|
|
380
393
|
};
|
|
381
394
|
const result = await client.callTool(params, import_types.CallToolResultSchema, {
|
|
382
395
|
timeout: config.timeout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\ttype IDataObject,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\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\nimport { getTools } from './loadOptions';\nimport type { McpToolIncludeMode } from './types';\nimport { createCallTool, getSelectedTools, McpToolkit, mcpToolToDynamicTool } from './utils';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\n/**\n * Get node parameters for MCP client configuration\n */\nfunction getNodeConfig(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\titemIndex: number,\n): {\n\tauthentication: McpAuthenticationOption;\n\ttimeout: number;\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\tmode: McpToolIncludeMode;\n\tincludeTools: string[];\n\texcludeTools: string[];\n} {\n\tconst node = ctx.getNode();\n\tconst authentication = ctx.getNodeParameter(\n\t\t'authentication',\n\t\titemIndex,\n\t) as McpAuthenticationOption;\n\tconst timeout = ctx.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = ctx.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t} else {\n\t\tserverTransport = ctx.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\tendpointUrl = ctx.getNodeParameter('endpointUrl', itemIndex) as string;\n\t}\n\n\tconst mode = ctx.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\tconst includeTools = ctx.getNodeParameter('includeTools', itemIndex, []) as string[];\n\tconst excludeTools = ctx.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\treturn {\n\t\tauthentication,\n\t\ttimeout,\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\tmode,\n\t\tincludeTools,\n\t\texcludeTools,\n\t};\n}\n\n/**\n * Connect to MCP server and get filtered tools\n */\nasync function connectAndGetTools(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\tconfig: ReturnType<typeof getNodeConfig>,\n) {\n\tconst node = ctx.getNode();\n\tconst { headers } = await getAuthHeaders(ctx, config.authentication);\n\n\tconst client = await connectMcpClient({\n\t\tserverTransport: config.serverTransport,\n\t\tendpointUrl: config.endpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) =>\n\t\t\tawait tryRefreshOAuth2Token(ctx, config.authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\treturn { client, mcpTools: null, error: client.error };\n\t}\n\n\tconst allTools = await getAllTools(client.result);\n\tconst mcpTools = getSelectedTools({\n\t\ttools: allTools,\n\t\tmode: config.mode,\n\t\tincludeTools: config.includeTools,\n\t\texcludeTools: config.excludeTools,\n\t});\n\n\treturn { client: client.result, mcpTools, error: null };\n}\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\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\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lt: 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: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\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\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: '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', 'mcpOAuth2Api', 'multipleHeadersAuth'],\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 node = this.getNode();\n\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\tconst setError = (error: NodeOperationError): SupplyData => {\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\tif (error) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', { error });\n\t\t\treturn setError(mapToNodeOperationError(node, error));\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tif (!mcpTools?.length) {\n\t\t\treturn setError(\n\t\t\t\tnew NodeOperationError(node, 'MCP Server returned no tools', {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t\t}),\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, config.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.close() };\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst node = this.getNode();\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst item = items[itemIndex];\n\t\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new NodeOperationError(node, error.error, { itemIndex });\n\t\t\t}\n\n\t\t\tif (!mcpTools?.length) {\n\t\t\t\tthrow new NodeOperationError(node, 'MCP Server returned no tools', { itemIndex });\n\t\t\t}\n\n\t\t\tfor (const tool of mcpTools) {\n\t\t\t\t// Check for tool name in item.json.tool (for toolkit execution from agent)\n\t\t\t\t// or item.tool (for direct execution)\n\t\t\t\tif (!item.json.tool || typeof item.json.tool !== 'string') {\n\t\t\t\t\tthrow new NodeOperationError(node, 'Tool name not found in item.json.tool or item.tool', {\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst toolName = item.json.tool;\n\t\t\t\tif (toolName === tool.name) {\n\t\t\t\t\t// Extract the tool name from arguments before passing to MCP\n\t\t\t\t\tconst { tool: _, ...toolArguments } = item.json;\n\t\t\t\t\tconst params: {\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t\targuments: IDataObject;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\targuments: toolArguments,\n\t\t\t\t\t};\n\t\t\t\t\tconst result = await client.callTool(params, CallToolResultSchema, {\n\t\t\t\t\t\ttimeout: config.timeout,\n\t\t\t\t\t});\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tresponse: result.content as IDataObject,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\t\titem: itemIndex,\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}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["import_utils","headers","error"]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\ttype IDataObject,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\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\nimport { getTools } from './loadOptions';\nimport type { McpToolIncludeMode } from './types';\nimport { createCallTool, getSelectedTools, McpToolkit, mcpToolToDynamicTool } from './utils';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\nimport type { JSONSchema7 } from 'json-schema';\nimport pick from 'lodash/pick';\n\n/**\n * Get node parameters for MCP client configuration\n */\nfunction getNodeConfig(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\titemIndex: number,\n): {\n\tauthentication: McpAuthenticationOption;\n\ttimeout: number;\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\tmode: McpToolIncludeMode;\n\tincludeTools: string[];\n\texcludeTools: string[];\n} {\n\tconst node = ctx.getNode();\n\tconst authentication = ctx.getNodeParameter(\n\t\t'authentication',\n\t\titemIndex,\n\t) as McpAuthenticationOption;\n\tconst timeout = ctx.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = ctx.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t} else {\n\t\tserverTransport = ctx.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\tendpointUrl = ctx.getNodeParameter('endpointUrl', itemIndex) as string;\n\t}\n\n\tconst mode = ctx.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\tconst includeTools = ctx.getNodeParameter('includeTools', itemIndex, []) as string[];\n\tconst excludeTools = ctx.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\treturn {\n\t\tauthentication,\n\t\ttimeout,\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\tmode,\n\t\tincludeTools,\n\t\texcludeTools,\n\t};\n}\n\n/**\n * Connect to MCP server and get filtered tools\n */\nasync function connectAndGetTools(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\tconfig: ReturnType<typeof getNodeConfig>,\n) {\n\tconst node = ctx.getNode();\n\tconst { headers } = await getAuthHeaders(ctx, config.authentication);\n\n\tconst client = await connectMcpClient({\n\t\tserverTransport: config.serverTransport,\n\t\tendpointUrl: config.endpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) =>\n\t\t\tawait tryRefreshOAuth2Token(ctx, config.authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\treturn { client, mcpTools: null, error: client.error };\n\t}\n\n\tconst allTools = await getAllTools(client.result);\n\tconst mcpTools = getSelectedTools({\n\t\ttools: allTools,\n\t\tmode: config.mode,\n\t\tincludeTools: config.includeTools,\n\t\texcludeTools: config.excludeTools,\n\t});\n\n\treturn { client: client.result, mcpTools, error: null };\n}\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\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\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lt: 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: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\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\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: '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', 'mcpOAuth2Api', 'multipleHeadersAuth'],\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 node = this.getNode();\n\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\tconst setError = (error: NodeOperationError): SupplyData => {\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\tif (error) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', { error });\n\t\t\treturn setError(mapToNodeOperationError(node, error));\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tif (!mcpTools?.length) {\n\t\t\treturn setError(\n\t\t\t\tnew NodeOperationError(node, 'MCP Server returned no tools', {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t\t}),\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, config.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.close() };\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst node = this.getNode();\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst item = items[itemIndex];\n\t\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new NodeOperationError(node, error.error, { itemIndex });\n\t\t\t}\n\n\t\t\tif (!mcpTools?.length) {\n\t\t\t\tthrow new NodeOperationError(node, 'MCP Server returned no tools', { itemIndex });\n\t\t\t}\n\n\t\t\tfor (const tool of mcpTools) {\n\t\t\t\t// Check for tool name in item.json.tool (for toolkit execution from agent)\n\t\t\t\t// or item.tool (for direct execution)\n\t\t\t\tif (!item.json.tool || typeof item.json.tool !== 'string') {\n\t\t\t\t\tthrow new NodeOperationError(node, 'Tool name not found in item.json.tool or item.tool', {\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst toolName = item.json.tool;\n\t\t\t\tif (toolName === tool.name) {\n\t\t\t\t\t// Extract the tool name from arguments before passing to MCP\n\t\t\t\t\tconst { tool: _, ...toolArguments } = item.json;\n\t\t\t\t\tconst schema: JSONSchema7 = tool.inputSchema;\n\t\t\t\t\t// When additionalProperties is explicitly false, filter to schema-defined properties.\n\t\t\t\t\t// Otherwise (true or omitted), pass all arguments through\n\t\t\t\t\tconst sanitizedToolArguments: IDataObject =\n\t\t\t\t\t\tschema.additionalProperties === false\n\t\t\t\t\t\t\t? pick(toolArguments, Object.keys(schema.properties ?? {}))\n\t\t\t\t\t\t\t: toolArguments;\n\n\t\t\t\t\tconst params: {\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t\targuments: IDataObject;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\targuments: sanitizedToolArguments,\n\t\t\t\t\t};\n\t\t\t\t\tconst result = await client.callTool(params, CallToolResultSchema, {\n\t\t\t\t\t\ttimeout: config.timeout,\n\t\t\t\t\t});\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tresponse: result.content as IDataObject,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\t\titem: itemIndex,\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}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["import_utils","headers","error","pick"]}
|
|
@@ -26,7 +26,6 @@ var import_config = require("@n8n/config");
|
|
|
26
26
|
var import_di = require("@n8n/di");
|
|
27
27
|
var import_JavaScriptSandbox = require("n8n-nodes-base/dist/nodes/Code/JavaScriptSandbox");
|
|
28
28
|
var import_JsTaskRunnerSandbox = require("n8n-nodes-base/dist/nodes/Code/JsTaskRunnerSandbox");
|
|
29
|
-
var import_PythonSandbox = require("n8n-nodes-base/dist/nodes/Code/PythonSandbox");
|
|
30
29
|
var import_PythonTaskRunnerSandbox = require("n8n-nodes-base/dist/nodes/Code/PythonTaskRunnerSandbox");
|
|
31
30
|
var import_Sandbox = require("n8n-nodes-base/dist/nodes/Code/Sandbox");
|
|
32
31
|
var import_n8n_workflow = require("n8n-workflow");
|
|
@@ -48,7 +47,6 @@ function getTool(ctx, itemIndex, log = true) {
|
|
|
48
47
|
const workflowMode = ctx.getMode();
|
|
49
48
|
const runnersConfig = import_di.Container.get(import_config.TaskRunnersConfig);
|
|
50
49
|
const isJsRunnerEnabled = runnersConfig.enabled;
|
|
51
|
-
const isPyRunnerEnabled = runnersConfig.isNativePythonRunnerEnabled;
|
|
52
50
|
const { typeVersion } = node;
|
|
53
51
|
const name = typeVersion <= 1.1 ? ctx.getNodeParameter("name", itemIndex) : (0, import_n8n_workflow.nodeNameToToolName)(node);
|
|
54
52
|
const description = ctx.getNodeParameter("description", itemIndex);
|
|
@@ -60,35 +58,31 @@ function getTool(ctx, itemIndex, log = true) {
|
|
|
60
58
|
} else {
|
|
61
59
|
code = ctx.getNodeParameter("pythonCode", itemIndex);
|
|
62
60
|
}
|
|
63
|
-
const
|
|
64
|
-
const context = import_Sandbox.getSandboxContext.call(ctx, index);
|
|
65
|
-
context.query = query;
|
|
66
|
-
let sandbox;
|
|
61
|
+
const runFunction = async (query) => {
|
|
67
62
|
if (language === "javaScript") {
|
|
68
|
-
|
|
63
|
+
if (isJsRunnerEnabled) {
|
|
64
|
+
const sandbox = new import_JsTaskRunnerSandbox.JsTaskRunnerSandbox(
|
|
65
|
+
code,
|
|
66
|
+
"runOnceForAllItems",
|
|
67
|
+
workflowMode,
|
|
68
|
+
ctx,
|
|
69
|
+
void 0,
|
|
70
|
+
{
|
|
71
|
+
query
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
return await sandbox.runCodeForTool();
|
|
75
|
+
} else {
|
|
76
|
+
const context = import_Sandbox.getSandboxContext.call(ctx, itemIndex);
|
|
77
|
+
context.query = query;
|
|
78
|
+
const sandbox = new import_JavaScriptSandbox.JavaScriptSandbox(context, code, ctx.helpers);
|
|
79
|
+
sandbox.on(
|
|
80
|
+
"output",
|
|
81
|
+
workflowMode === "manual" ? ctx.sendMessageToUI.bind(ctx) : (...args) => console.log(`[Workflow "${ctx.getWorkflow().id}"][Node "${node.name}"]`, ...args)
|
|
82
|
+
);
|
|
83
|
+
return await sandbox.runCode();
|
|
84
|
+
}
|
|
69
85
|
} else {
|
|
70
|
-
sandbox = new import_PythonSandbox.PythonSandbox(context, code, ctx.helpers);
|
|
71
|
-
}
|
|
72
|
-
sandbox.on(
|
|
73
|
-
"output",
|
|
74
|
-
workflowMode === "manual" ? ctx.sendMessageToUI.bind(ctx) : (...args) => console.log(`[Workflow "${ctx.getWorkflow().id}"][Node "${node.name}"]`, ...args)
|
|
75
|
-
);
|
|
76
|
-
return sandbox;
|
|
77
|
-
};
|
|
78
|
-
const runFunction = async (query) => {
|
|
79
|
-
if (language === "javaScript" && isJsRunnerEnabled) {
|
|
80
|
-
const sandbox = new import_JsTaskRunnerSandbox.JsTaskRunnerSandbox(
|
|
81
|
-
code,
|
|
82
|
-
"runOnceForAllItems",
|
|
83
|
-
workflowMode,
|
|
84
|
-
ctx,
|
|
85
|
-
void 0,
|
|
86
|
-
{
|
|
87
|
-
query
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
return await sandbox.runCodeForTool();
|
|
91
|
-
} else if (language === "python" && isPyRunnerEnabled) {
|
|
92
86
|
const sandbox = new import_PythonTaskRunnerSandbox.PythonTaskRunnerSandbox(
|
|
93
87
|
code,
|
|
94
88
|
"runOnceForAllItems",
|
|
@@ -99,9 +93,6 @@ function getTool(ctx, itemIndex, log = true) {
|
|
|
99
93
|
}
|
|
100
94
|
);
|
|
101
95
|
return await sandbox.runCodeForTool();
|
|
102
|
-
} else {
|
|
103
|
-
const sandbox = getSandbox(query, itemIndex);
|
|
104
|
-
return await sandbox.runCode();
|
|
105
96
|
}
|
|
106
97
|
};
|
|
107
98
|
const toolHandler = async (query) => {
|
|
@@ -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 { PythonTaskRunnerSandbox } from 'n8n-nodes-base/dist/nodes/Code/PythonTaskRunnerSandbox';\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 isJsRunnerEnabled = runnersConfig.enabled;\n\tconst isPyRunnerEnabled = runnersConfig.isNativePythonRunnerEnabled;\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' && isJsRunnerEnabled) {\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\treturn await sandbox.runCodeForTool();\n\t\t} else if (language === 'python' && isPyRunnerEnabled) {\n\t\t\tconst sandbox = new PythonTaskRunnerSandbox(\n\t\t\t\tcode,\n\t\t\t\t'runOnceForAllItems',\n\t\t\t\tworkflowMode,\n\t\t\t\tctx as IExecuteFunctions,\n\t\t\t\t{\n\t\t\t\t\tquery,\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn await sandbox.runCodeForTool();\n\t\t} else {\n\t\t\t// use old vm2-based sandbox when runners disabled\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":[]}
|
|
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 { PythonTaskRunnerSandbox } from 'n8n-nodes-base/dist/nodes/Code/PythonTaskRunnerSandbox';\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 isJsRunnerEnabled = 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\tconst runFunction = async (query: string | IDataObject): Promise<unknown> => {\n\t\tif (language === 'javaScript') {\n\t\t\tif (isJsRunnerEnabled) {\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\tctx,\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\treturn await sandbox.runCodeForTool();\n\t\t\t} else {\n\t\t\t\tconst context = getSandboxContext.call(ctx, itemIndex);\n\t\t\t\tcontext.query = query;\n\t\t\t\tconst sandbox = new JavaScriptSandbox(context, code, ctx.helpers);\n\t\t\t\tsandbox.on(\n\t\t\t\t\t'output',\n\t\t\t\t\tworkflowMode === 'manual'\n\t\t\t\t\t\t? ctx.sendMessageToUI.bind(ctx)\n\t\t\t\t\t\t: (...args: unknown[]) =>\n\t\t\t\t\t\t\t\tconsole.log(`[Workflow \"${ctx.getWorkflow().id}\"][Node \"${node.name}\"]`, ...args),\n\t\t\t\t);\n\t\t\t\treturn await sandbox.runCode<string>();\n\t\t\t}\n\t\t} else {\n\t\t\tconst sandbox = new PythonTaskRunnerSandbox(\n\t\t\t\tcode,\n\t\t\t\t'runOnceForAllItems',\n\t\t\t\tworkflowMode,\n\t\t\t\tctx as IExecuteFunctions,\n\t\t\t\t{\n\t\t\t\t\tquery,\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn await sandbox.runCodeForTool();\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":[]}
|
|
@@ -42,17 +42,7 @@ const cssVariables = `
|
|
|
42
42
|
--chat--spacing: 1rem;
|
|
43
43
|
--chat--border-radius: 0.25rem;
|
|
44
44
|
--chat--transition-duration: 0.15s;
|
|
45
|
-
--chat--font-family:
|
|
46
|
-
-apple-system,
|
|
47
|
-
BlinkMacSystemFont,
|
|
48
|
-
'Segoe UI',
|
|
49
|
-
Roboto,
|
|
50
|
-
Oxygen-Sans,
|
|
51
|
-
Ubuntu,
|
|
52
|
-
Cantarell,
|
|
53
|
-
'Helvetica Neue',
|
|
54
|
-
sans-serif
|
|
55
|
-
);
|
|
45
|
+
--chat--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
|
|
56
46
|
|
|
57
47
|
/* Window Dimensions */
|
|
58
48
|
--chat--window--width: 400px;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/constants.ts"],"sourcesContent":["// CSS Variables are defined in `@n8n/chat/src/css/_tokens.scss`\nexport const cssVariables = `\n:root {\n /* Colors */\n --chat--color-primary: #e74266;\n --chat--color-primary-shade-50: #db4061;\n --chat--color-primary-shade-100: #cf3c5c;\n --chat--color-secondary: #20b69e;\n --chat--color-secondary-shade-50: #1ca08a;\n --chat--color-white: #ffffff;\n --chat--color-light: #f2f4f8;\n --chat--color-light-shade-50: #e6e9f1;\n --chat--color-light-shade-100: #c2c5cc;\n --chat--color-medium: #d2d4d9;\n --chat--color-dark: #101330;\n --chat--color-disabled: #d2d4d9;\n --chat--color-typing: #404040;\n\n /* Base Layout */\n --chat--spacing: 1rem;\n --chat--border-radius: 0.25rem;\n --chat--transition-duration: 0.15s;\n --chat--font-family:
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/constants.ts"],"sourcesContent":["// CSS Variables are defined in `@n8n/chat/src/css/_tokens.scss`\nexport const cssVariables = `\n:root {\n /* Colors */\n --chat--color-primary: #e74266;\n --chat--color-primary-shade-50: #db4061;\n --chat--color-primary-shade-100: #cf3c5c;\n --chat--color-secondary: #20b69e;\n --chat--color-secondary-shade-50: #1ca08a;\n --chat--color-white: #ffffff;\n --chat--color-light: #f2f4f8;\n --chat--color-light-shade-50: #e6e9f1;\n --chat--color-light-shade-100: #c2c5cc;\n --chat--color-medium: #d2d4d9;\n --chat--color-dark: #101330;\n --chat--color-disabled: #d2d4d9;\n --chat--color-typing: #404040;\n\n /* Base Layout */\n --chat--spacing: 1rem;\n --chat--border-radius: 0.25rem;\n --chat--transition-duration: 0.15s;\n --chat--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;\n\n /* Window Dimensions */\n --chat--window--width: 400px;\n --chat--window--height: 600px;\n --chat--window--bottom: var(--chat--spacing);\n --chat--window--right: var(--chat--spacing);\n --chat--window--z-index: 9999;\n --chat--window--border: 1px solid var(--chat--color-light-shade-50);\n --chat--window--border-radius: var(--chat--border-radius);\n --chat--window--margin-bottom: var(--chat--spacing);\n\n /* Header Styles */\n --chat--header-height: auto;\n --chat--header--padding: var(--chat--spacing);\n --chat--header--background: var(--chat--color-dark);\n --chat--header--color: var(--chat--color-light);\n --chat--header--border-top: none;\n --chat--header--border-bottom: none;\n --chat--header--border-left: none;\n --chat--header--border-right: none;\n --chat--heading--font-size: 2em;\n --chat--subtitle--font-size: inherit;\n --chat--subtitle--line-height: 1.8;\n\n /* Message Styles */\n --chat--message--font-size: 1rem;\n --chat--message--padding: var(--chat--spacing);\n --chat--message--border-radius: var(--chat--border-radius);\n --chat--message-line-height: 1.5;\n --chat--message--margin-bottom: calc(var(--chat--spacing) * 1);\n --chat--message--bot--background: var(--chat--color-white);\n --chat--message--bot--color: var(--chat--color-dark);\n --chat--message--bot--border: none;\n --chat--message--user--background: var(--chat--color-secondary);\n --chat--message--user--color: var(--chat--color-white);\n --chat--message--user--border: none;\n --chat--message--pre--background: rgba(0, 0, 0, 0.05);\n --chat--messages-list--padding: var(--chat--spacing);\n\n /* Toggle Button */\n --chat--toggle--size: 64px;\n --chat--toggle--width: var(--chat--toggle--size);\n --chat--toggle--height: var(--chat--toggle--size);\n --chat--toggle--border-radius: 50%;\n --chat--toggle--background: var(--chat--color-primary);\n --chat--toggle--hover--background: var(--chat--color-primary-shade-50);\n --chat--toggle--active--background: var(--chat--color-primary-shade-100);\n --chat--toggle--color: var(--chat--color-white);\n\n /* Input Area */\n --chat--textarea--height: 50px;\n --chat--textarea--max-height: 30rem;\n --chat--input--font-size: inherit;\n --chat--input--border: 0;\n --chat--input--border-radius: 0;\n --chat--input--padding: 0.8rem;\n --chat--input--background: var(--chat--color-white);\n --chat--input--text-color: initial;\n --chat--input--line-height: 1.5;\n --chat--input--placeholder--font-size: var(--chat--input--font-size);\n --chat--input--border-active: 0;\n --chat--input--left--panel--width: 2rem;\n\n /* Button Styles */\n --chat--button--color: var(--chat--color-light);\n --chat--button--background: var(--chat--color-primary);\n --chat--button--padding: calc(var(--chat--spacing) * 1 / 2) var(--chat--spacing);\n --chat--button--border-radius: var(--chat--border-radius);\n --chat--button--hover--color: var(--chat--color-light);\n --chat--button--hover--background: var(--chat--color-primary-shade-50);\n --chat--close--button--color-hover: var(--chat--color-primary);\n\n /* Send and File Buttons */\n --chat--input--send--button--background: var(--chat--color-white);\n --chat--input--send--button--color: var(--chat--color-secondary);\n --chat--input--send--button--background-hover: var(--chat--color-primary-shade-50);\n --chat--input--send--button--color-hover: var(--chat--color-secondary-shade-50);\n --chat--input--file--button--background: var(--chat--color-white);\n --chat--input--file--button--color: var(--chat--color-secondary);\n --chat--input--file--button--background-hover: var(--chat--input--file--button--background);\n --chat--input--file--button--color-hover: var(--chat--color-secondary-shade-50);\n --chat--files-spacing: 0.25rem;\n\n /* Body and Footer */\n --chat--body--background: var(--chat--color-light);\n --chat--footer--background: var(--chat--color-light);\n --chat--footer--color: var(--chat--color-dark);\n}\n`;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACO,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
|
|
@@ -21,26 +21,64 @@ __export(VectorStoreWeaviate_node_exports, {
|
|
|
21
21
|
VectorStoreWeaviate: () => VectorStoreWeaviate
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(VectorStoreWeaviate_node_exports);
|
|
24
|
+
var import_documents = require("@langchain/core/documents");
|
|
24
25
|
var import_weaviate = require("@langchain/weaviate");
|
|
26
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
25
27
|
var import_Weaviate = require("./Weaviate.utils");
|
|
26
28
|
var import_createVectorStoreNode = require("../shared/createVectorStoreNode/createVectorStoreNode");
|
|
27
29
|
var import_listSearch = require("../shared/createVectorStoreNode/methods/listSearch");
|
|
28
30
|
var import_descriptions = require("../shared/descriptions");
|
|
29
31
|
class ExtendedWeaviateVectorStore extends import_weaviate.WeaviateStore {
|
|
30
32
|
static async fromExistingCollection(embeddings, args, defaultFilter) {
|
|
33
|
+
const ctor = this;
|
|
34
|
+
const baseCandidate = await ctor.fromExistingIndex(embeddings, args);
|
|
35
|
+
if (!(baseCandidate instanceof ExtendedWeaviateVectorStore)) {
|
|
36
|
+
throw new import_n8n_workflow.ApplicationError(
|
|
37
|
+
"Weaviate store factory did not return an ExtendedWeaviateVectorStore instance"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
const base = baseCandidate;
|
|
41
|
+
base.args = args;
|
|
31
42
|
if (defaultFilter) {
|
|
32
|
-
|
|
43
|
+
base.defaultFilter = defaultFilter;
|
|
33
44
|
}
|
|
34
|
-
return
|
|
45
|
+
return base;
|
|
35
46
|
}
|
|
36
47
|
async similaritySearchVectorWithScore(query, k, filter) {
|
|
37
|
-
filter = filter ??
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
filter = filter ?? this.defaultFilter;
|
|
49
|
+
const args = this.args;
|
|
50
|
+
if (args.hybridQuery) {
|
|
51
|
+
const options = {
|
|
52
|
+
limit: k ?? void 0,
|
|
53
|
+
autoLimit: args.autoCutLimit ?? void 0,
|
|
54
|
+
alpha: args.alpha ?? void 0,
|
|
55
|
+
vector: query,
|
|
56
|
+
filter: filter ? (0, import_Weaviate.parseCompositeFilter)(filter) : void 0,
|
|
57
|
+
queryProperties: args.queryProperties ? args.queryProperties.split(",").map((prop) => prop.trim()) : void 0,
|
|
58
|
+
maxVectorDistance: args.maxVectorDistance ?? void 0,
|
|
59
|
+
fusionType: args.fusionType,
|
|
60
|
+
returnMetadata: args.hybridExplainScore ? ["explainScore"] : void 0
|
|
61
|
+
};
|
|
62
|
+
const content = await super.hybridSearch(args.hybridQuery, options);
|
|
63
|
+
return content.map((doc) => {
|
|
64
|
+
const { score, ...metadata } = doc.metadata;
|
|
65
|
+
if (typeof score !== "number") {
|
|
66
|
+
throw new import_n8n_workflow.ApplicationError(`Unexpected score type: ${typeof score}`);
|
|
67
|
+
}
|
|
68
|
+
return [
|
|
69
|
+
new import_documents.Document({
|
|
70
|
+
pageContent: doc.pageContent,
|
|
71
|
+
metadata
|
|
72
|
+
}),
|
|
73
|
+
score
|
|
74
|
+
];
|
|
75
|
+
});
|
|
43
76
|
}
|
|
77
|
+
return await super.similaritySearchVectorWithScore(
|
|
78
|
+
query,
|
|
79
|
+
k,
|
|
80
|
+
filter ? (0, import_Weaviate.parseCompositeFilter)(filter) : void 0
|
|
81
|
+
);
|
|
44
82
|
}
|
|
45
83
|
}
|
|
46
84
|
const sharedFields = [import_descriptions.weaviateCollectionRLC];
|
|
@@ -148,6 +186,71 @@ const retrieveFields = [
|
|
|
148
186
|
validateType: "string",
|
|
149
187
|
description: "Select the metadata to retrieve along the content"
|
|
150
188
|
},
|
|
189
|
+
{
|
|
190
|
+
displayName: "Hybrid: Query Text",
|
|
191
|
+
name: "hybridQuery",
|
|
192
|
+
type: "string",
|
|
193
|
+
default: "",
|
|
194
|
+
validateType: "string",
|
|
195
|
+
description: "Provide a query text to combine vector search with a keyword/text search"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
displayName: "Hybrid: Explain Score",
|
|
199
|
+
name: "hybridExplainScore",
|
|
200
|
+
type: "boolean",
|
|
201
|
+
default: false,
|
|
202
|
+
validateType: "boolean",
|
|
203
|
+
description: "Whether to show the score fused between hybrid and vector search explanation"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
displayName: "Hybrid: Fusion Type",
|
|
207
|
+
name: "fusionType",
|
|
208
|
+
type: "options",
|
|
209
|
+
options: [
|
|
210
|
+
{
|
|
211
|
+
name: "Relative Score",
|
|
212
|
+
value: "RelativeScore"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "Ranked",
|
|
216
|
+
value: "Ranked"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
default: "RelativeScore",
|
|
220
|
+
description: "Select the fusion type for combining vector and keyword search results"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
displayName: "Hybrid: Auto Cut Limit",
|
|
224
|
+
name: "autoCutLimit",
|
|
225
|
+
type: "number",
|
|
226
|
+
default: void 0,
|
|
227
|
+
validateType: "number",
|
|
228
|
+
description: "Limit result groups by detecting sudden jumps in score"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
displayName: "Hybrid: Alpha",
|
|
232
|
+
name: "alpha",
|
|
233
|
+
type: "number",
|
|
234
|
+
default: 0.5,
|
|
235
|
+
validateType: "number",
|
|
236
|
+
description: "Change the relative weights of the keyword and vector components. 1.0 = pure vector, 0.0 = pure keyword."
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
displayName: "Hybrid: Query Properties",
|
|
240
|
+
name: "queryProperties",
|
|
241
|
+
type: "string",
|
|
242
|
+
default: "",
|
|
243
|
+
validateType: "string",
|
|
244
|
+
description: 'Comma-separated list of properties to include in the query with optionally weighted values, e.g., "question^2,answer"'
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
displayName: "Hybrid: Max Vector Distance",
|
|
248
|
+
name: "maxVectorDistance",
|
|
249
|
+
type: "number",
|
|
250
|
+
default: void 0,
|
|
251
|
+
validateType: "number",
|
|
252
|
+
description: "Set the maximum allowable distance for the vector search component"
|
|
253
|
+
},
|
|
151
254
|
...shared_options
|
|
152
255
|
]
|
|
153
256
|
}
|
|
@@ -197,9 +300,16 @@ class VectorStoreWeaviate extends (0, import_createVectorStoreNode.createVectorS
|
|
|
197
300
|
const config = {
|
|
198
301
|
client,
|
|
199
302
|
indexName: collection,
|
|
200
|
-
tenant: options.tenant
|
|
303
|
+
tenant: options.tenant ?? void 0,
|
|
201
304
|
textKey: options.textKey ? options.textKey : "text",
|
|
202
|
-
metadataKeys
|
|
305
|
+
metadataKeys,
|
|
306
|
+
hybridQuery: options.hybridQuery ?? void 0,
|
|
307
|
+
autoCutLimit: options.autoCutLimit ?? void 0,
|
|
308
|
+
alpha: options.alpha ?? void 0,
|
|
309
|
+
queryProperties: options.queryProperties,
|
|
310
|
+
maxVectorDistance: options.maxVectorDistance,
|
|
311
|
+
fusionType: options.fusionType,
|
|
312
|
+
hybridExplainScore: options.hybridExplainScore ?? false
|
|
203
313
|
};
|
|
204
314
|
const validFilter = filter && Object.keys(filter).length > 0 ? filter : void 0;
|
|
205
315
|
return await ExtendedWeaviateVectorStore.fromExistingCollection(
|
|
@@ -219,7 +329,7 @@ class VectorStoreWeaviate extends (0, import_createVectorStoreNode.createVectorS
|
|
|
219
329
|
const config = {
|
|
220
330
|
client,
|
|
221
331
|
indexName: collectionName,
|
|
222
|
-
tenant: options.tenant
|
|
332
|
+
tenant: options.tenant ?? void 0,
|
|
223
333
|
textKey: options.textKey ? options.textKey : "text",
|
|
224
334
|
metadataKeys
|
|
225
335
|
};
|