@n8n/n8n-nodes-langchain 1.115.0 → 1.116.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.
Files changed (194) hide show
  1. package/dist/credentials/AnthropicApi.credentials.js +39 -8
  2. package/dist/credentials/AnthropicApi.credentials.js.map +1 -1
  3. package/dist/credentials/LemonadeApi.credentials.js +70 -0
  4. package/dist/credentials/LemonadeApi.credentials.js.map +1 -0
  5. package/dist/known/credentials.json +9 -0
  6. package/dist/known/nodes.json +12 -0
  7. package/dist/nodes/agents/Agent/Agent.node.js +1 -2
  8. package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
  9. package/dist/nodes/agents/Agent/V1/AgentV1.node.js +2 -0
  10. package/dist/nodes/agents/Agent/V1/AgentV1.node.js.map +1 -1
  11. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/description.js +13 -1
  12. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/description.js.map +1 -1
  13. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/execute.js +49 -30
  14. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/execute.js.map +1 -1
  15. package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js +3 -0
  16. package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js.map +1 -1
  17. package/dist/nodes/embeddings/EmbeddingsLemonade/EmbeddingsLemonade.node.js +87 -0
  18. package/dist/nodes/embeddings/EmbeddingsLemonade/EmbeddingsLemonade.node.js.map +1 -0
  19. package/dist/nodes/embeddings/EmbeddingsLemonade/lemonade.svg +53 -0
  20. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js +17 -0
  21. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js.map +1 -1
  22. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +12 -8
  23. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
  24. package/dist/nodes/llms/LMChatLemonade/LmChatLemonade.node.js +106 -0
  25. package/dist/nodes/llms/LMChatLemonade/LmChatLemonade.node.js.map +1 -0
  26. package/dist/nodes/llms/LMChatLemonade/lemonade.svg +53 -0
  27. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js +6 -5
  28. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js.map +1 -1
  29. package/dist/nodes/llms/LMLemonade/LmLemonade.node.js +107 -0
  30. package/dist/nodes/llms/LMLemonade/LmLemonade.node.js.map +1 -0
  31. package/dist/nodes/llms/LMLemonade/description.js +147 -0
  32. package/dist/nodes/llms/LMLemonade/description.js.map +1 -0
  33. package/dist/nodes/llms/LMLemonade/lemonade.svg +53 -0
  34. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js +3 -0
  35. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js.map +1 -1
  36. package/dist/nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.js +14 -1
  37. package/dist/nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.js.map +1 -1
  38. package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +107 -47
  39. package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
  40. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +2 -1
  41. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
  42. package/dist/nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.js +43 -4
  43. package/dist/nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.js.map +1 -1
  44. package/dist/nodes/vendors/Anthropic/transport/index.js +9 -5
  45. package/dist/nodes/vendors/Anthropic/transport/index.js.map +1 -1
  46. package/dist/nodes/vendors/OpenAi/OpenAi.node.js +50 -11
  47. package/dist/nodes/vendors/OpenAi/OpenAi.node.js.map +1 -1
  48. package/dist/nodes/vendors/OpenAi/helpers/binary-data.js +3 -3
  49. package/dist/nodes/vendors/OpenAi/helpers/binary-data.js.map +1 -1
  50. package/dist/nodes/vendors/OpenAi/helpers/description.js +75 -0
  51. package/dist/nodes/vendors/OpenAi/helpers/description.js.map +1 -0
  52. package/dist/nodes/vendors/OpenAi/helpers/interfaces.js.map +1 -1
  53. package/dist/nodes/vendors/OpenAi/helpers/modelFiltering.js +34 -0
  54. package/dist/nodes/vendors/OpenAi/helpers/modelFiltering.js.map +1 -0
  55. package/dist/nodes/vendors/OpenAi/helpers/polling.js +52 -0
  56. package/dist/nodes/vendors/OpenAi/helpers/polling.js.map +1 -0
  57. package/dist/nodes/vendors/OpenAi/helpers/utils.js +27 -0
  58. package/dist/nodes/vendors/OpenAi/helpers/utils.js.map +1 -1
  59. package/dist/nodes/vendors/OpenAi/methods/listSearch.js +10 -6
  60. package/dist/nodes/vendors/OpenAi/methods/listSearch.js.map +1 -1
  61. package/dist/nodes/vendors/OpenAi/v1/OpenAiV1.node.js +110 -0
  62. package/dist/nodes/vendors/OpenAi/v1/OpenAiV1.node.js.map +1 -0
  63. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/create.operation.js +1 -1
  64. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/create.operation.js.map +1 -0
  65. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/deleteAssistant.operation.js +1 -1
  66. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/deleteAssistant.operation.js.map +1 -0
  67. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/index.js.map +1 -0
  68. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/list.operation.js +1 -1
  69. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/list.operation.js.map +1 -0
  70. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/message.operation.js +5 -5
  71. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js.map +1 -0
  72. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/update.operation.js +1 -1
  73. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/update.operation.js.map +1 -0
  74. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/audio/generate.operation.js +1 -1
  75. package/dist/nodes/vendors/OpenAi/v1/actions/audio/generate.operation.js.map +1 -0
  76. package/dist/nodes/vendors/OpenAi/v1/actions/audio/index.js.map +1 -0
  77. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/audio/transcribe.operation.js +2 -2
  78. package/dist/nodes/vendors/OpenAi/v1/actions/audio/transcribe.operation.js.map +1 -0
  79. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/audio/translate.operation.js +2 -2
  80. package/dist/nodes/vendors/OpenAi/v1/actions/audio/translate.operation.js.map +1 -0
  81. package/dist/nodes/vendors/OpenAi/v1/actions/descriptions.js.map +1 -0
  82. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/file/deleteFile.operation.js +1 -1
  83. package/dist/nodes/vendors/OpenAi/v1/actions/file/deleteFile.operation.js.map +1 -0
  84. package/dist/nodes/vendors/OpenAi/v1/actions/file/index.js.map +1 -0
  85. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/file/list.operation.js +1 -1
  86. package/dist/nodes/vendors/OpenAi/v1/actions/file/list.operation.js.map +1 -0
  87. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/file/upload.operation.js +2 -2
  88. package/dist/nodes/vendors/OpenAi/v1/actions/file/upload.operation.js.map +1 -0
  89. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/image/analyze.operation.js +1 -1
  90. package/dist/nodes/vendors/OpenAi/v1/actions/image/analyze.operation.js.map +1 -0
  91. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/image/generate.operation.js +1 -1
  92. package/dist/nodes/vendors/OpenAi/v1/actions/image/generate.operation.js.map +1 -0
  93. package/dist/nodes/vendors/OpenAi/v1/actions/image/index.js.map +1 -0
  94. package/dist/nodes/vendors/OpenAi/v1/actions/node.type.js.map +1 -0
  95. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/router.js +1 -1
  96. package/dist/nodes/vendors/OpenAi/v1/actions/router.js.map +1 -0
  97. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/text/classify.operation.js +1 -1
  98. package/dist/nodes/vendors/OpenAi/v1/actions/text/classify.operation.js.map +1 -0
  99. package/dist/nodes/vendors/OpenAi/v1/actions/text/index.js.map +1 -0
  100. package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/text/message.operation.js +4 -4
  101. package/dist/nodes/vendors/OpenAi/v1/actions/text/message.operation.js.map +1 -0
  102. package/dist/nodes/vendors/OpenAi/v2/OpenAiV2.node.js +116 -0
  103. package/dist/nodes/vendors/OpenAi/v2/OpenAiV2.node.js.map +1 -0
  104. package/dist/nodes/vendors/OpenAi/v2/actions/audio/generate.operation.js +197 -0
  105. package/dist/nodes/vendors/OpenAi/v2/actions/audio/generate.operation.js.map +1 -0
  106. package/dist/nodes/vendors/OpenAi/v2/actions/audio/index.js +96 -0
  107. package/dist/nodes/vendors/OpenAi/v2/actions/audio/index.js.map +1 -0
  108. package/dist/nodes/vendors/OpenAi/v2/actions/audio/transcribe.operation.js +121 -0
  109. package/dist/nodes/vendors/OpenAi/v2/actions/audio/transcribe.operation.js.map +1 -0
  110. package/dist/nodes/vendors/OpenAi/v2/actions/audio/translate.operation.js +111 -0
  111. package/dist/nodes/vendors/OpenAi/v2/actions/audio/translate.operation.js.map +1 -0
  112. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/create.operation.js +120 -0
  113. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/create.operation.js.map +1 -0
  114. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/get.operation.js +60 -0
  115. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/get.operation.js.map +1 -0
  116. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/index.js +94 -0
  117. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/index.js.map +1 -0
  118. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/remove.operation.js +60 -0
  119. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/remove.operation.js.map +1 -0
  120. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/update.operation.js +75 -0
  121. package/dist/nodes/vendors/OpenAi/v2/actions/conversation/update.operation.js.map +1 -0
  122. package/dist/nodes/vendors/OpenAi/v2/actions/descriptions.js +279 -0
  123. package/dist/nodes/vendors/OpenAi/v2/actions/descriptions.js.map +1 -0
  124. package/dist/nodes/vendors/OpenAi/v2/actions/file/deleteFile.operation.js +84 -0
  125. package/dist/nodes/vendors/OpenAi/v2/actions/file/deleteFile.operation.js.map +1 -0
  126. package/dist/nodes/vendors/OpenAi/v2/actions/file/index.js +84 -0
  127. package/dist/nodes/vendors/OpenAi/v2/actions/file/index.js.map +1 -0
  128. package/dist/nodes/vendors/OpenAi/v2/actions/file/list.operation.js +92 -0
  129. package/dist/nodes/vendors/OpenAi/v2/actions/file/list.operation.js.map +1 -0
  130. package/dist/nodes/vendors/OpenAi/v2/actions/file/upload.operation.js +130 -0
  131. package/dist/nodes/vendors/OpenAi/v2/actions/file/upload.operation.js.map +1 -0
  132. package/dist/nodes/vendors/OpenAi/v2/actions/image/analyze.operation.js +211 -0
  133. package/dist/nodes/vendors/OpenAi/v2/actions/image/analyze.operation.js.map +1 -0
  134. package/dist/nodes/vendors/OpenAi/v2/actions/image/edit.operation.js +464 -0
  135. package/dist/nodes/vendors/OpenAi/v2/actions/image/edit.operation.js.map +1 -0
  136. package/dist/nodes/vendors/OpenAi/v2/actions/image/generate.operation.js +319 -0
  137. package/dist/nodes/vendors/OpenAi/v2/actions/image/generate.operation.js.map +1 -0
  138. package/dist/nodes/vendors/OpenAi/v2/actions/image/index.js +84 -0
  139. package/dist/nodes/vendors/OpenAi/v2/actions/image/index.js.map +1 -0
  140. package/dist/nodes/vendors/OpenAi/v2/actions/node.type.js +17 -0
  141. package/dist/nodes/vendors/OpenAi/v2/actions/node.type.js.map +1 -0
  142. package/dist/nodes/vendors/OpenAi/v2/actions/router.js +111 -0
  143. package/dist/nodes/vendors/OpenAi/v2/actions/router.js.map +1 -0
  144. package/dist/nodes/vendors/OpenAi/v2/actions/text/classify.operation.js +102 -0
  145. package/dist/nodes/vendors/OpenAi/v2/actions/text/classify.operation.js.map +1 -0
  146. package/dist/nodes/vendors/OpenAi/v2/actions/text/helpers/responses.js +277 -0
  147. package/dist/nodes/vendors/OpenAi/v2/actions/text/helpers/responses.js.map +1 -0
  148. package/dist/nodes/vendors/OpenAi/v2/actions/text/index.js +86 -0
  149. package/dist/nodes/vendors/OpenAi/v2/actions/text/index.js.map +1 -0
  150. package/dist/nodes/vendors/OpenAi/v2/actions/text/message.operation.js +345 -0
  151. package/dist/nodes/vendors/OpenAi/v2/actions/text/message.operation.js.map +1 -0
  152. package/dist/nodes/vendors/OpenAi/v2/actions/text/response.operation.js +777 -0
  153. package/dist/nodes/vendors/OpenAi/v2/actions/text/response.operation.js.map +1 -0
  154. package/dist/nodes/vendors/OpenAi/v2/actions/video/generate.operation.js +199 -0
  155. package/dist/nodes/vendors/OpenAi/v2/actions/video/generate.operation.js.map +1 -0
  156. package/dist/nodes/vendors/OpenAi/v2/actions/video/index.js +64 -0
  157. package/dist/nodes/vendors/OpenAi/v2/actions/video/index.js.map +1 -0
  158. package/dist/types/credentials.json +2 -1
  159. package/dist/types/nodes.json +10 -6
  160. package/dist/utils/helpers.js +22 -2
  161. package/dist/utils/helpers.js.map +1 -1
  162. package/package.json +17 -13
  163. package/dist/nodes/vendors/OpenAi/actions/assistant/create.operation.js.map +0 -1
  164. package/dist/nodes/vendors/OpenAi/actions/assistant/deleteAssistant.operation.js.map +0 -1
  165. package/dist/nodes/vendors/OpenAi/actions/assistant/index.js.map +0 -1
  166. package/dist/nodes/vendors/OpenAi/actions/assistant/list.operation.js.map +0 -1
  167. package/dist/nodes/vendors/OpenAi/actions/assistant/message.operation.js.map +0 -1
  168. package/dist/nodes/vendors/OpenAi/actions/assistant/update.operation.js.map +0 -1
  169. package/dist/nodes/vendors/OpenAi/actions/audio/generate.operation.js.map +0 -1
  170. package/dist/nodes/vendors/OpenAi/actions/audio/index.js.map +0 -1
  171. package/dist/nodes/vendors/OpenAi/actions/audio/transcribe.operation.js.map +0 -1
  172. package/dist/nodes/vendors/OpenAi/actions/audio/translate.operation.js.map +0 -1
  173. package/dist/nodes/vendors/OpenAi/actions/descriptions.js.map +0 -1
  174. package/dist/nodes/vendors/OpenAi/actions/file/deleteFile.operation.js.map +0 -1
  175. package/dist/nodes/vendors/OpenAi/actions/file/index.js.map +0 -1
  176. package/dist/nodes/vendors/OpenAi/actions/file/list.operation.js.map +0 -1
  177. package/dist/nodes/vendors/OpenAi/actions/file/upload.operation.js.map +0 -1
  178. package/dist/nodes/vendors/OpenAi/actions/image/analyze.operation.js.map +0 -1
  179. package/dist/nodes/vendors/OpenAi/actions/image/generate.operation.js.map +0 -1
  180. package/dist/nodes/vendors/OpenAi/actions/image/index.js.map +0 -1
  181. package/dist/nodes/vendors/OpenAi/actions/node.type.js.map +0 -1
  182. package/dist/nodes/vendors/OpenAi/actions/router.js.map +0 -1
  183. package/dist/nodes/vendors/OpenAi/actions/text/classify.operation.js.map +0 -1
  184. package/dist/nodes/vendors/OpenAi/actions/text/index.js.map +0 -1
  185. package/dist/nodes/vendors/OpenAi/actions/text/message.operation.js.map +0 -1
  186. package/dist/nodes/vendors/OpenAi/actions/versionDescription.js +0 -160
  187. package/dist/nodes/vendors/OpenAi/actions/versionDescription.js.map +0 -1
  188. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/assistant/index.js +0 -0
  189. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/audio/index.js +0 -0
  190. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/descriptions.js +0 -0
  191. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/file/index.js +0 -0
  192. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/image/index.js +0 -0
  193. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/node.type.js +0 -0
  194. /package/dist/nodes/vendors/OpenAi/{actions → v1/actions}/text/index.js +0 -0
@@ -26,6 +26,7 @@ var import_n8n_workflow = require("n8n-workflow");
26
26
  var import_sharedFields = require("../../../utils/sharedFields");
27
27
  var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler");
28
28
  var import_N8nLlmTracing = require("../N8nLlmTracing");
29
+ const deprecatedMagistralModelsWithTextOutput = ["magistral-small-2506", "magistral-medium-2506"];
29
30
  class LmChatMistralCloud {
30
31
  constructor() {
31
32
  this.description = {
@@ -195,13 +196,25 @@ class LmChatMistralCloud {
195
196
  model: modelName,
196
197
  ...options,
197
198
  callbacks: [new import_N8nLlmTracing.N8nLlmTracing(this)],
198
- onFailedAttempt: (0, import_n8nLlmFailedAttemptHandler.makeN8nLlmFailedAttemptHandler)(this)
199
+ onFailedAttempt: (0, import_n8nLlmFailedAttemptHandler.makeN8nLlmFailedAttemptHandler)(this),
200
+ metadata: {
201
+ output_format: isModelWithJSONOutput(modelName) ? "json" : void 0
202
+ }
199
203
  });
200
204
  return {
201
205
  response: model
202
206
  };
203
207
  }
204
208
  }
209
+ function isModelWithJSONOutput(modelName) {
210
+ if (!modelName.includes("magistral")) {
211
+ return false;
212
+ }
213
+ if (deprecatedMagistralModelsWithTextOutput.includes(modelName)) {
214
+ return false;
215
+ }
216
+ return true;
217
+ }
205
218
  // Annotate the CommonJS export names for ESM import in node:
206
219
  0 && (module.exports = {
207
220
  LmChatMistralCloud
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.ts"],"sourcesContent":["import type { ChatMistralAIInput } from '@langchain/mistralai';\nimport { ChatMistralAI } from '@langchain/mistralai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatMistralCloud implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Mistral Cloud Chat Model',\n\n\t\tname: 'lmChatMistralCloud',\n\t\ticon: 'file:mistral.svg',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'Mistral Cloud Chat Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Chat Models (Recommended)'],\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.lmchatmistralcloud/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'mistralCloudApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL: 'https://api.mistral.ai/v1',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tname: 'model',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will generate the completion. <a href=\"https://docs.mistral.ai/platform/endpoints/\">Learn more</a>.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\turl: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ !$responseItem.id.includes('embed') }}\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{ $responseItem.id }}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{ $responseItem.id }}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'mistral-small',\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Enable Safe Mode',\n\t\t\t\t\t\tname: 'safeMode',\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdescription: 'Whether to inject a safety prompt before all conversations',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Random Seed',\n\t\t\t\t\t\tname: 'randomSeed',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The seed to use for random sampling. If set, different calls will generate deterministic results.',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials('mistralCloudApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\t\tconst options = this.getNodeParameter('options', itemIndex, {\n\t\t\tmaxRetries: 2,\n\t\t\ttopP: 1,\n\t\t\ttemperature: 0.7,\n\t\t\tmaxTokens: -1,\n\t\t\tsafeMode: false,\n\t\t\trandomSeed: undefined,\n\t\t}) as Partial<ChatMistralAIInput>;\n\n\t\tconst model = new ChatMistralAI({\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...options,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this),\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.ts"],"sourcesContent":["import type { ChatMistralAIInput } from '@langchain/mistralai';\nimport { ChatMistralAI } from '@langchain/mistralai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nconst deprecatedMagistralModelsWithTextOutput = ['magistral-small-2506', 'magistral-medium-2506'];\n\nexport class LmChatMistralCloud implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Mistral Cloud Chat Model',\n\n\t\tname: 'lmChatMistralCloud',\n\t\ticon: 'file:mistral.svg',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'Mistral Cloud Chat Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Chat Models (Recommended)'],\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.lmchatmistralcloud/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'mistralCloudApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL: 'https://api.mistral.ai/v1',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tname: 'model',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will generate the completion. <a href=\"https://docs.mistral.ai/platform/endpoints/\">Learn more</a>.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\turl: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ !$responseItem.id.includes('embed') }}\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{ $responseItem.id }}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{ $responseItem.id }}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'mistral-small',\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Enable Safe Mode',\n\t\t\t\t\t\tname: 'safeMode',\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdescription: 'Whether to inject a safety prompt before all conversations',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Random Seed',\n\t\t\t\t\t\tname: 'randomSeed',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The seed to use for random sampling. If set, different calls will generate deterministic results.',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials('mistralCloudApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\t\tconst options = this.getNodeParameter('options', itemIndex, {\n\t\t\tmaxRetries: 2,\n\t\t\ttopP: 1,\n\t\t\ttemperature: 0.7,\n\t\t\tmaxTokens: -1,\n\t\t\tsafeMode: false,\n\t\t\trandomSeed: undefined,\n\t\t}) as Partial<ChatMistralAIInput>;\n\n\t\tconst model = new ChatMistralAI({\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...options,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this),\n\t\t\tmetadata: {\n\t\t\t\toutput_format: isModelWithJSONOutput(modelName) ? 'json' : undefined,\n\t\t\t},\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n\nfunction isModelWithJSONOutput(modelName: string): boolean {\n\tif (!modelName.includes('magistral')) {\n\t\treturn false;\n\t}\n\n\tif (deprecatedMagistralModelsWithTextOutput.includes(modelName)) {\n\t\t// Deprecated Magistral models return text output\n\t\t// Includes <think></think> chunks as part of text content\n\t\treturn false;\n\t}\n\n\t// All future Magistral models will return JSON output\n\t// Which include \"thinking\" json types\n\t// https://docs.mistral.ai/capabilities/reasoning/\n\treturn true;\n}\n"],"mappings":"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","names":[]}
@@ -21,12 +21,63 @@ __export(McpClientTool_node_exports, {
21
21
  McpClientTool: () => McpClientTool
22
22
  });
23
23
  module.exports = __toCommonJS(McpClientTool_node_exports);
24
+ var import_n8n_workflow = require("n8n-workflow");
24
25
  var import_logWrapper = require("../../../utils/logWrapper");
25
26
  var import_sharedFields = require("../../../utils/sharedFields");
26
- var import_n8n_workflow = require("n8n-workflow");
27
27
  var import_descriptions = require("./descriptions");
28
28
  var import_loadOptions = require("./loadOptions");
29
29
  var import_utils = require("./utils");
30
+ function getNodeConfig(ctx, itemIndex) {
31
+ const node = ctx.getNode();
32
+ const authentication = ctx.getNodeParameter(
33
+ "authentication",
34
+ itemIndex
35
+ );
36
+ const timeout = ctx.getNodeParameter("options.timeout", itemIndex, 6e4);
37
+ let serverTransport;
38
+ let endpointUrl;
39
+ if (node.typeVersion === 1) {
40
+ serverTransport = "sse";
41
+ endpointUrl = ctx.getNodeParameter("sseEndpoint", itemIndex);
42
+ } else {
43
+ serverTransport = ctx.getNodeParameter("serverTransport", itemIndex);
44
+ endpointUrl = ctx.getNodeParameter("endpointUrl", itemIndex);
45
+ }
46
+ const mode = ctx.getNodeParameter("include", itemIndex);
47
+ const includeTools = ctx.getNodeParameter("includeTools", itemIndex, []);
48
+ const excludeTools = ctx.getNodeParameter("excludeTools", itemIndex, []);
49
+ return {
50
+ authentication,
51
+ timeout,
52
+ serverTransport,
53
+ endpointUrl,
54
+ mode,
55
+ includeTools,
56
+ excludeTools
57
+ };
58
+ }
59
+ async function connectAndGetTools(ctx, config) {
60
+ const node = ctx.getNode();
61
+ const { headers } = await (0, import_utils.getAuthHeaders)(ctx, config.authentication);
62
+ const client = await (0, import_utils.connectMcpClient)({
63
+ serverTransport: config.serverTransport,
64
+ endpointUrl: config.endpointUrl,
65
+ headers,
66
+ name: node.type,
67
+ version: node.typeVersion
68
+ });
69
+ if (!client.ok) {
70
+ return { client, mcpTools: null, error: client.error };
71
+ }
72
+ const allTools = await (0, import_utils.getAllTools)(client.result);
73
+ const mcpTools = (0, import_utils.getSelectedTools)({
74
+ tools: allTools,
75
+ mode: config.mode,
76
+ includeTools: config.includeTools,
77
+ excludeTools: config.excludeTools
78
+ });
79
+ return { client: client.result, mcpTools, error: null };
80
+ }
30
81
  class McpClientTool {
31
82
  constructor() {
32
83
  this.description = {
@@ -241,39 +292,17 @@ class McpClientTool {
241
292
  };
242
293
  }
243
294
  async supplyData(itemIndex) {
244
- const authentication = this.getNodeParameter(
245
- "authentication",
246
- itemIndex
247
- );
248
295
  const node = this.getNode();
249
- const timeout = this.getNodeParameter("options.timeout", itemIndex, 6e4);
250
- let serverTransport;
251
- let endpointUrl;
252
- if (node.typeVersion === 1) {
253
- serverTransport = "sse";
254
- endpointUrl = this.getNodeParameter("sseEndpoint", itemIndex);
255
- } else {
256
- serverTransport = this.getNodeParameter("serverTransport", itemIndex);
257
- endpointUrl = this.getNodeParameter("endpointUrl", itemIndex);
258
- }
259
- const { headers } = await (0, import_utils.getAuthHeaders)(this, authentication);
260
- const client = await (0, import_utils.connectMcpClient)({
261
- serverTransport,
262
- endpointUrl,
263
- headers,
264
- name: node.type,
265
- version: node.typeVersion
266
- });
296
+ const config = getNodeConfig(this, itemIndex);
267
297
  const setError = (message, description) => {
268
- const error = new import_n8n_workflow.NodeOperationError(node, message, { itemIndex, description });
269
- this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error);
270
- throw error;
298
+ const error2 = new import_n8n_workflow.NodeOperationError(node, message, { itemIndex, description });
299
+ this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error2);
300
+ throw error2;
271
301
  };
272
- if (!client.ok) {
273
- this.logger.error("McpClientTool: Failed to connect to MCP Server", {
274
- error: client.error
275
- });
276
- switch (client.error.type) {
302
+ const { client, mcpTools, error } = await connectAndGetTools(this, config);
303
+ if (error) {
304
+ this.logger.error("McpClientTool: Failed to connect to MCP Server", { error });
305
+ switch (error.type) {
277
306
  case "invalid_url":
278
307
  return setError("Could not connect to your MCP server. The provided URL is invalid.");
279
308
  case "connection":
@@ -282,17 +311,7 @@ class McpClientTool {
282
311
  }
283
312
  }
284
313
  this.logger.debug("McpClientTool: Successfully connected to MCP Server");
285
- const mode = this.getNodeParameter("include", itemIndex);
286
- const includeTools = this.getNodeParameter("includeTools", itemIndex, []);
287
- const excludeTools = this.getNodeParameter("excludeTools", itemIndex, []);
288
- const allTools = await (0, import_utils.getAllTools)(client.result);
289
- const mcpTools = (0, import_utils.getSelectedTools)({
290
- tools: allTools,
291
- mode,
292
- includeTools,
293
- excludeTools
294
- });
295
- if (!mcpTools.length) {
314
+ if (!mcpTools || !mcpTools.length) {
296
315
  return setError(
297
316
  "MCP Server returned no tools",
298
317
  "Connected successfully to your MCP server but it returned an empty list of tools."
@@ -302,10 +321,10 @@ class McpClientTool {
302
321
  (tool) => (0, import_logWrapper.logWrapper)(
303
322
  (0, import_utils.mcpToolToDynamicTool)(
304
323
  tool,
305
- (0, import_utils.createCallTool)(tool.name, client.result, timeout, (errorMessage) => {
306
- const error = new import_n8n_workflow.NodeOperationError(node, errorMessage, { itemIndex });
307
- void this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error);
308
- this.logger.error(`McpClientTool: Tool "${tool.name}" failed to execute`, { error });
324
+ (0, import_utils.createCallTool)(tool.name, client, config.timeout, (errorMessage) => {
325
+ const error2 = new import_n8n_workflow.NodeOperationError(node, errorMessage, { itemIndex });
326
+ void this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error2);
327
+ this.logger.error(`McpClientTool: Tool "${tool.name}" failed to execute`, { error: error2 });
309
328
  })
310
329
  ),
311
330
  this
@@ -313,7 +332,48 @@ class McpClientTool {
313
332
  );
314
333
  this.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);
315
334
  const toolkit = new import_utils.McpToolkit(tools);
316
- return { response: toolkit, closeFunction: async () => await client.result.close() };
335
+ return { response: toolkit, closeFunction: async () => await client.close() };
336
+ }
337
+ async execute() {
338
+ const node = this.getNode();
339
+ const items = this.getInputData();
340
+ const returnData = [];
341
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
342
+ const item = items[itemIndex];
343
+ const config = getNodeConfig(this, itemIndex);
344
+ const { client, mcpTools, error } = await connectAndGetTools(this, config);
345
+ if (error) {
346
+ throw new import_n8n_workflow.NodeOperationError(node, error.error, { itemIndex });
347
+ }
348
+ if (!mcpTools?.length) {
349
+ throw new import_n8n_workflow.NodeOperationError(node, "MCP Server returned no tools", { itemIndex });
350
+ }
351
+ for (const tool of mcpTools) {
352
+ if (!item.json.tool || typeof item.json.tool !== "string") {
353
+ throw new import_n8n_workflow.NodeOperationError(node, "Tool name not found in item.json.tool or item.tool", {
354
+ itemIndex
355
+ });
356
+ }
357
+ const toolName = item.json.tool;
358
+ if (toolName === tool.name) {
359
+ const { tool: _, ...toolArguments } = item.json;
360
+ const params = {
361
+ name: tool.name,
362
+ arguments: toolArguments
363
+ };
364
+ const result = await client.callTool(params);
365
+ returnData.push({
366
+ json: {
367
+ response: result.content
368
+ },
369
+ pairedItem: {
370
+ item: itemIndex
371
+ }
372
+ });
373
+ }
374
+ }
375
+ }
376
+ return [returnData];
317
377
  }
318
378
  }
319
379
  // Annotate the CommonJS export names for ESM import in node:
@@ -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 { 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":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import {\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 { 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\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});\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\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 node = this.getNode();\n\t\tconst config = getNodeConfig(this, itemIndex);\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\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\n\t\t\tswitch (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\tif (!mcpTools || !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, 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);\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":["error"]}
@@ -120,8 +120,9 @@ class WorkflowToolService {
120
120
  [responseData],
121
121
  metadata
122
122
  );
123
+ return processedResponse;
123
124
  }
124
- return processedResponse;
125
+ return responseData;
125
126
  } catch (error) {
126
127
  if (abortSignal?.aborted) {
127
128
  return 'There was an error: "Execution was cancelled"';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.ts"],"sourcesContent":["import type { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport isArray from 'lodash/isArray';\nimport isObject from 'lodash/isObject';\nimport type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces';\nimport * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode';\nimport { getCurrentWorkflowInputData } from 'n8n-nodes-base/dist/utils/workflowInputsResourceMapping/GenericFunctions';\nimport type {\n\tExecuteWorkflowData,\n\tExecutionError,\n\tFromAIArgument,\n\tIDataObject,\n\tIExecuteFunctions,\n\tIExecuteWorkflowInfo,\n\tINodeExecutionData,\n\tINodeParameterResourceLocator,\n\tISupplyDataFunctions,\n\tITaskMetadata,\n\tIWorkflowBase,\n\tIWorkflowDataProxyData,\n\tResourceMapperValue,\n} from 'n8n-workflow';\nimport {\n\tgenerateZodSchema,\n\tjsonParse,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tparseErrorMetadata,\n\tsleepWithAbort,\n\ttraverseNodeParameters,\n} from 'n8n-workflow';\nimport { z } from 'zod';\n\nfunction isNodeExecutionData(data: unknown): data is INodeExecutionData[] {\n\treturn isArray(data) && Boolean(data.length) && isObject(data[0]) && 'json' in data[0];\n}\n\n/**\n\tMain class for creating the Workflow tool\n\tProcesses the node parameters and creates AI Agent tool capable of executing n8n workflows\n*/\nexport class WorkflowToolService {\n\t// Determines if we should use input schema when creating the tool\n\tprivate useSchema: boolean;\n\n\t// Sub-workflow id, pulled from referenced sub-workflow\n\tprivate subWorkflowId: string | undefined;\n\n\t// Sub-workflow execution id, will be set after the sub-workflow is executed\n\tprivate subExecutionId: string | undefined;\n\n\tprivate returnAllItems: boolean = false;\n\n\tconstructor(\n\t\tprivate baseContext: ISupplyDataFunctions | IExecuteFunctions,\n\t\toptions?: { returnAllItems: boolean },\n\t) {\n\t\tconst subWorkflowInputs = this.baseContext.getNode().parameters\n\t\t\t.workflowInputs as ResourceMapperValue;\n\t\tthis.useSchema = (subWorkflowInputs?.schema ?? []).length > 0;\n\t\tthis.returnAllItems = options?.returnAllItems ?? false;\n\t}\n\n\t// Creates the tool based on the provided parameters\n\tasync createTool({\n\t\tctx,\n\t\tname,\n\t\tdescription,\n\t\titemIndex,\n\t\tmanualLogging = true,\n\t}: {\n\t\tctx: ISupplyDataFunctions | IExecuteFunctions;\n\t\tname: string;\n\t\tdescription: string;\n\t\titemIndex: number;\n\t\tmanualLogging?: boolean;\n\t}): Promise<DynamicTool | DynamicStructuredTool> {\n\t\t// Handler for the tool execution, will be called when the tool is executed\n\t\t// This function will execute the sub-workflow and return the response\n\t\t// We get the runIndex from the context to handle multiple executions\n\t\t// of the same tool when the tool is used in a loop or in a parallel execution.\n\t\tconst node = ctx.getNode();\n\n\t\tlet runIndex: number = 'getNextRunIndex' in ctx ? ctx.getNextRunIndex() : 0;\n\t\tconst toolHandler = async (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t): Promise<IDataObject | IDataObject[] | string> => {\n\t\t\tlet maxTries = 1;\n\t\t\tif (node.retryOnFail === true) {\n\t\t\t\tmaxTries = Math.min(5, Math.max(2, node.maxTries ?? 3));\n\t\t\t}\n\n\t\t\tlet waitBetweenTries = 0;\n\t\t\tif (node.retryOnFail === true) {\n\t\t\t\twaitBetweenTries = Math.min(5000, Math.max(0, node.waitBetweenTries ?? 1000));\n\t\t\t}\n\n\t\t\tlet lastError: ExecutionError | undefined;\n\n\t\t\tfor (let tryIndex = 0; tryIndex < maxTries; tryIndex++) {\n\t\t\t\tconst localRunIndex = runIndex++;\n\n\t\t\t\tlet context = this.baseContext;\n\t\t\t\t// We need to clone the context here to handle runIndex correctly\n\t\t\t\t// Otherwise the runIndex will be shared between different executions\n\t\t\t\t// Causing incorrect data to be passed to the sub-workflow and via $fromAI\n\t\t\t\tif ('cloneWith' in this.baseContext) {\n\t\t\t\t\tcontext = this.baseContext.cloneWith({\n\t\t\t\t\t\trunIndex: localRunIndex,\n\t\t\t\t\t\tinputData: [[{ json: { query } }]],\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Get abort signal from context for cancellation support\n\t\t\t\tconst abortSignal = context.getExecutionCancelSignal?.();\n\n\t\t\t\t// Check if execution was cancelled before retry\n\t\t\t\tif (abortSignal?.aborted) {\n\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t}\n\n\t\t\t\tif (tryIndex !== 0) {\n\t\t\t\t\t// Reset error from previous attempt\n\t\t\t\t\tlastError = undefined;\n\t\t\t\t\tif (waitBetweenTries !== 0) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait sleepWithAbort(waitBetweenTries, abortSignal);\n\t\t\t\t\t\t} catch (abortError) {\n\t\t\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await this.runFunction(context, query, itemIndex, runManager);\n\n\t\t\t\t\tconst processedResponse = this.handleToolResponse(response);\n\n\t\t\t\t\tlet responseData: INodeExecutionData[];\n\t\t\t\t\tif (isNodeExecutionData(response)) {\n\t\t\t\t\t\tresponseData = response;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst reParsedData = jsonParse<IDataObject>(processedResponse, {\n\t\t\t\t\t\t\tfallbackValue: { response: processedResponse },\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tresponseData = [{ json: reParsedData }];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Once the sub-workflow is executed, add the output data to the context\n\t\t\t\t\t// This will be used to link the sub-workflow execution in the parent workflow\n\t\t\t\t\tlet metadata: ITaskMetadata | undefined;\n\t\t\t\t\tif (this.subExecutionId && this.subWorkflowId) {\n\t\t\t\t\t\tmetadata = {\n\t\t\t\t\t\t\tsubExecution: {\n\t\t\t\t\t\t\t\texecutionId: this.subExecutionId,\n\t\t\t\t\t\t\t\tworkflowId: this.subWorkflowId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (manualLogging) {\n\t\t\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t\t\t[responseData],\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn processedResponse;\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Check if error is due to cancellation\n\t\t\t\t\tif (abortSignal?.aborted) {\n\t\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t\t}\n\n\t\t\t\t\tconst executionError = error as ExecutionError;\n\t\t\t\t\tlastError = executionError;\n\t\t\t\t\tconst errorResponse = `There was an error: \"${executionError.message}\"`;\n\n\t\t\t\t\tif (manualLogging) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t\t\texecutionError,\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (tryIndex === maxTries - 1) {\n\t\t\t\t\t\treturn errorResponse;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn `There was an error: ${lastError?.message ?? 'Unknown error'}`;\n\t\t};\n\n\t\t// Create structured tool if input schema is provided\n\t\treturn this.useSchema\n\t\t\t? await this.createStructuredTool(name, description, toolHandler)\n\t\t\t: new DynamicTool({ name, description, func: toolHandler });\n\t}\n\n\tprivate handleToolResponse(response: unknown): string {\n\t\tif (typeof response === 'number') {\n\t\t\treturn response.toString();\n\t\t}\n\n\t\tif (isNodeExecutionData(response)) {\n\t\t\treturn JSON.stringify(\n\t\t\t\tresponse.map((item) => item.json),\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t);\n\t\t}\n\n\t\tif (isObject(response)) {\n\t\t\treturn JSON.stringify(response, null, 2);\n\t\t}\n\n\t\tif (typeof response !== 'string') {\n\t\t\tthrow new NodeOperationError(this.baseContext.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}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Executes specified sub-workflow with provided inputs\n\t */\n\tprivate async executeSubWorkflow(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tworkflowInfo: IExecuteWorkflowInfo,\n\t\titems: INodeExecutionData[],\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<{ response: string | IDataObject | INodeExecutionData[]; subExecutionId: string }> {\n\t\tlet receivedData: ExecuteWorkflowData;\n\t\ttry {\n\t\t\treceivedData = await context.executeWorkflow(workflowInfo, items, runManager?.getChild(), {\n\t\t\t\tparentExecution: {\n\t\t\t\t\texecutionId: workflowProxy.$execution.id,\n\t\t\t\t\tworkflowId: workflowProxy.$workflow.id,\n\t\t\t\t},\n\t\t\t});\n\t\t\t// Set sub-workflow execution id so it can be used in other places\n\t\t\tthis.subExecutionId = receivedData.executionId;\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(context.getNode(), error as Error);\n\t\t}\n\n\t\tlet response: IDataObject | INodeExecutionData[] | undefined;\n\t\tif (this.returnAllItems) {\n\t\t\tresponse = receivedData?.data?.[0]?.length ? receivedData.data[0] : undefined;\n\t\t} else {\n\t\t\tresponse = receivedData?.data?.[0]?.[0]?.json;\n\t\t}\n\t\tif (response === undefined) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'There was an error: \"The workflow did not return a response\"',\n\t\t\t);\n\t\t}\n\n\t\treturn { response, subExecutionId: receivedData.executionId };\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source and executes it.\n\t * This function will be called as part of the tool execution (from the toolHandler)\n\t */\n\tprivate async runFunction(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<string | IDataObject | INodeExecutionData[]> {\n\t\tconst source = context.getNodeParameter('source', itemIndex) as string;\n\t\tconst workflowProxy = context.getWorkflowDataProxy(0);\n\n\t\tconst { workflowInfo } = await this.getSubWorkflowInfo(\n\t\t\tcontext,\n\t\t\tsource,\n\t\t\titemIndex,\n\t\t\tworkflowProxy,\n\t\t);\n\t\tconst rawData = this.prepareRawData(context, query, itemIndex);\n\t\tconst items = await this.prepareWorkflowItems(context, query, itemIndex, rawData);\n\n\t\tthis.subWorkflowId = workflowInfo.id;\n\n\t\tconst { response } = await this.executeSubWorkflow(\n\t\t\tcontext,\n\t\t\tworkflowInfo,\n\t\t\titems,\n\t\t\tworkflowProxy,\n\t\t\trunManager,\n\t\t);\n\t\treturn response;\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source (database or parameter)\n\t */\n\tprivate async getSubWorkflowInfo(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tsource: string,\n\t\titemIndex: number,\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t): Promise<{\n\t\tworkflowInfo: IExecuteWorkflowInfo;\n\t\tsubWorkflowId: string;\n\t}> {\n\t\tconst workflowInfo: IExecuteWorkflowInfo = {};\n\t\tlet subWorkflowId: string;\n\n\t\tif (source === 'database') {\n\t\t\tconst { value } = context.getNodeParameter(\n\t\t\t\t'workflowId',\n\t\t\t\titemIndex,\n\t\t\t\t{},\n\t\t\t) as INodeParameterResourceLocator;\n\t\t\tworkflowInfo.id = value as string;\n\t\t\tsubWorkflowId = workflowInfo.id;\n\t\t} else if (source === 'parameter') {\n\t\t\tconst workflowJson = context.getNodeParameter('workflowJson', itemIndex) as string;\n\t\t\ttry {\n\t\t\t\tworkflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase;\n\t\t\t\t// subworkflow is same as parent workflow\n\t\t\t\tsubWorkflowId = workflowProxy.$workflow.id;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`The provided workflow is not valid JSON: \"${(error as Error).message}\"`,\n\t\t\t\t\t{ itemIndex },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn { workflowInfo, subWorkflowId: subWorkflowId! };\n\t}\n\n\tprivate prepareRawData(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t): IDataObject {\n\t\tconst rawData: IDataObject = { query };\n\t\tconst workflowFieldsJson = context.getNodeParameter('fields.values', itemIndex, [], {\n\t\t\trawExpressions: true,\n\t\t}) as SetField[];\n\n\t\t// Copied from Set Node v2\n\t\tfor (const entry of workflowFieldsJson) {\n\t\t\tif (entry.type === 'objectValue' && (entry.objectValue as string).startsWith('=')) {\n\t\t\t\trawData[entry.name] = (entry.objectValue as string).replace(/^=+/, '');\n\t\t\t}\n\t\t}\n\n\t\treturn rawData;\n\t}\n\n\t/**\n\t * Prepares the sub-workflow items for execution\n\t */\n\tprivate async prepareWorkflowItems(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trawData: IDataObject,\n\t): Promise<INodeExecutionData[]> {\n\t\tconst options: SetNodeOptions = { include: 'all' };\n\t\tlet jsonData = typeof query === 'object' ? query : { query };\n\n\t\tif (this.useSchema) {\n\t\t\tconst currentWorkflowInputs = getCurrentWorkflowInputData.call(context);\n\t\t\tjsonData = currentWorkflowInputs[itemIndex].json;\n\t\t}\n\n\t\tconst newItem = await manual.execute.call(\n\t\t\tcontext,\n\t\t\t{ json: jsonData },\n\t\t\titemIndex,\n\t\t\toptions,\n\t\t\trawData,\n\t\t\tcontext.getNode(),\n\t\t);\n\n\t\treturn [newItem] as INodeExecutionData[];\n\t}\n\n\t/**\n\t * Create structured tool by parsing the sub-workflow input schema\n\t */\n\tprivate async createStructuredTool(\n\t\tname: string,\n\t\tdescription: string,\n\t\tfunc: (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t) => Promise<string | IDataObject | IDataObject[]>,\n\t): Promise<DynamicStructuredTool | DynamicTool> {\n\t\tconst collectedArguments = await this.extractFromAIParameters();\n\n\t\t// If there are no `fromAI` arguments, fallback to creating a simple tool\n\t\tif (collectedArguments.length === 0) {\n\t\t\treturn new DynamicTool({ name, description, func });\n\t\t}\n\n\t\t// Otherwise, prepare Zod schema and create a structured tool\n\t\tconst schema = this.createZodSchema(collectedArguments);\n\t\treturn new DynamicStructuredTool({ schema, name, description, func });\n\t}\n\n\tprivate async extractFromAIParameters(): Promise<FromAIArgument[]> {\n\t\tconst collectedArguments: FromAIArgument[] = [];\n\t\ttraverseNodeParameters(this.baseContext.getNode().parameters, collectedArguments);\n\n\t\tconst uniqueArgsMap = new Map<string, FromAIArgument>();\n\t\tfor (const arg of collectedArguments) {\n\t\t\tuniqueArgsMap.set(arg.key, arg);\n\t\t}\n\n\t\treturn Array.from(uniqueArgsMap.values());\n\t}\n\n\tprivate createZodSchema(args: FromAIArgument[]): z.ZodObject<any> {\n\t\tconst schemaObj = args.reduce((acc: Record<string, z.ZodTypeAny>, placeholder) => {\n\t\t\tacc[placeholder.key] = generateZodSchema(placeholder);\n\t\t\treturn acc;\n\t\t}, {});\n\n\t\treturn z.object(schemaObj).required();\n\t}\n}\n"],"mappings":"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","names":["isArray","isObject"]}
1
+ {"version":3,"sources":["../../../../../../nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.ts"],"sourcesContent":["import type { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport isArray from 'lodash/isArray';\nimport isObject from 'lodash/isObject';\nimport type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces';\nimport * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode';\nimport { getCurrentWorkflowInputData } from 'n8n-nodes-base/dist/utils/workflowInputsResourceMapping/GenericFunctions';\nimport type {\n\tExecuteWorkflowData,\n\tExecutionError,\n\tFromAIArgument,\n\tIDataObject,\n\tIExecuteFunctions,\n\tIExecuteWorkflowInfo,\n\tINodeExecutionData,\n\tINodeParameterResourceLocator,\n\tISupplyDataFunctions,\n\tITaskMetadata,\n\tIWorkflowBase,\n\tIWorkflowDataProxyData,\n\tResourceMapperValue,\n} from 'n8n-workflow';\nimport {\n\tgenerateZodSchema,\n\tjsonParse,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tparseErrorMetadata,\n\tsleepWithAbort,\n\ttraverseNodeParameters,\n} from 'n8n-workflow';\nimport { z } from 'zod';\n\nfunction isNodeExecutionData(data: unknown): data is INodeExecutionData[] {\n\treturn isArray(data) && Boolean(data.length) && isObject(data[0]) && 'json' in data[0];\n}\n\n/**\n\tMain class for creating the Workflow tool\n\tProcesses the node parameters and creates AI Agent tool capable of executing n8n workflows\n*/\nexport class WorkflowToolService {\n\t// Determines if we should use input schema when creating the tool\n\tprivate useSchema: boolean;\n\n\t// Sub-workflow id, pulled from referenced sub-workflow\n\tprivate subWorkflowId: string | undefined;\n\n\t// Sub-workflow execution id, will be set after the sub-workflow is executed\n\tprivate subExecutionId: string | undefined;\n\n\tprivate returnAllItems: boolean = false;\n\n\tconstructor(\n\t\tprivate baseContext: ISupplyDataFunctions | IExecuteFunctions,\n\t\toptions?: { returnAllItems: boolean },\n\t) {\n\t\tconst subWorkflowInputs = this.baseContext.getNode().parameters\n\t\t\t.workflowInputs as ResourceMapperValue;\n\t\tthis.useSchema = (subWorkflowInputs?.schema ?? []).length > 0;\n\t\tthis.returnAllItems = options?.returnAllItems ?? false;\n\t}\n\n\t// Creates the tool based on the provided parameters\n\tasync createTool({\n\t\tctx,\n\t\tname,\n\t\tdescription,\n\t\titemIndex,\n\t\tmanualLogging = true,\n\t}: {\n\t\tctx: ISupplyDataFunctions | IExecuteFunctions;\n\t\tname: string;\n\t\tdescription: string;\n\t\titemIndex: number;\n\t\tmanualLogging?: boolean;\n\t}): Promise<DynamicTool | DynamicStructuredTool> {\n\t\t// Handler for the tool execution, will be called when the tool is executed\n\t\t// This function will execute the sub-workflow and return the response\n\t\t// We get the runIndex from the context to handle multiple executions\n\t\t// of the same tool when the tool is used in a loop or in a parallel execution.\n\t\tconst node = ctx.getNode();\n\n\t\tlet runIndex: number = 'getNextRunIndex' in ctx ? ctx.getNextRunIndex() : 0;\n\t\tconst toolHandler = async (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t): Promise<IDataObject | IDataObject[] | string> => {\n\t\t\tlet maxTries = 1;\n\t\t\tif (node.retryOnFail === true) {\n\t\t\t\tmaxTries = Math.min(5, Math.max(2, node.maxTries ?? 3));\n\t\t\t}\n\n\t\t\tlet waitBetweenTries = 0;\n\t\t\tif (node.retryOnFail === true) {\n\t\t\t\twaitBetweenTries = Math.min(5000, Math.max(0, node.waitBetweenTries ?? 1000));\n\t\t\t}\n\n\t\t\tlet lastError: ExecutionError | undefined;\n\n\t\t\tfor (let tryIndex = 0; tryIndex < maxTries; tryIndex++) {\n\t\t\t\tconst localRunIndex = runIndex++;\n\n\t\t\t\tlet context = this.baseContext;\n\t\t\t\t// We need to clone the context here to handle runIndex correctly\n\t\t\t\t// Otherwise the runIndex will be shared between different executions\n\t\t\t\t// Causing incorrect data to be passed to the sub-workflow and via $fromAI\n\t\t\t\tif ('cloneWith' in this.baseContext) {\n\t\t\t\t\tcontext = this.baseContext.cloneWith({\n\t\t\t\t\t\trunIndex: localRunIndex,\n\t\t\t\t\t\tinputData: [[{ json: { query } }]],\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Get abort signal from context for cancellation support\n\t\t\t\tconst abortSignal = context.getExecutionCancelSignal?.();\n\n\t\t\t\t// Check if execution was cancelled before retry\n\t\t\t\tif (abortSignal?.aborted) {\n\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t}\n\n\t\t\t\tif (tryIndex !== 0) {\n\t\t\t\t\t// Reset error from previous attempt\n\t\t\t\t\tlastError = undefined;\n\t\t\t\t\tif (waitBetweenTries !== 0) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait sleepWithAbort(waitBetweenTries, abortSignal);\n\t\t\t\t\t\t} catch (abortError) {\n\t\t\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await this.runFunction(context, query, itemIndex, runManager);\n\n\t\t\t\t\tconst processedResponse = this.handleToolResponse(response);\n\n\t\t\t\t\tlet responseData: INodeExecutionData[];\n\t\t\t\t\tif (isNodeExecutionData(response)) {\n\t\t\t\t\t\tresponseData = response;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst reParsedData = jsonParse<IDataObject>(processedResponse, {\n\t\t\t\t\t\t\tfallbackValue: { response: processedResponse },\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tresponseData = [{ json: reParsedData }];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Once the sub-workflow is executed, add the output data to the context\n\t\t\t\t\t// This will be used to link the sub-workflow execution in the parent workflow\n\t\t\t\t\tlet metadata: ITaskMetadata | undefined;\n\t\t\t\t\tif (this.subExecutionId && this.subWorkflowId) {\n\t\t\t\t\t\tmetadata = {\n\t\t\t\t\t\t\tsubExecution: {\n\t\t\t\t\t\t\t\texecutionId: this.subExecutionId,\n\t\t\t\t\t\t\t\tworkflowId: this.subWorkflowId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// If manualLogging is enabled we've been called by the AgentExecutor\n\t\t\t\t\t// and have to return a stringified response.\n\t\t\t\t\tif (manualLogging) {\n\t\t\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t\t\t[responseData],\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn processedResponse;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If manualLogging is false we've been called by the engine and need\n\t\t\t\t\t// the structured response.\n\t\t\t\t\treturn responseData;\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Check if error is due to cancellation\n\t\t\t\t\tif (abortSignal?.aborted) {\n\t\t\t\t\t\treturn 'There was an error: \"Execution was cancelled\"';\n\t\t\t\t\t}\n\n\t\t\t\t\tconst executionError = error as ExecutionError;\n\t\t\t\t\tlastError = executionError;\n\t\t\t\t\tconst errorResponse = `There was an error: \"${executionError.message}\"`;\n\n\t\t\t\t\tif (manualLogging) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t\t\texecutionError,\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (tryIndex === maxTries - 1) {\n\t\t\t\t\t\treturn errorResponse;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn `There was an error: ${lastError?.message ?? 'Unknown error'}`;\n\t\t};\n\n\t\t// Create structured tool if input schema is provided\n\t\treturn this.useSchema\n\t\t\t? await this.createStructuredTool(name, description, toolHandler)\n\t\t\t: new DynamicTool({ name, description, func: toolHandler });\n\t}\n\n\tprivate handleToolResponse(response: unknown): string {\n\t\tif (typeof response === 'number') {\n\t\t\treturn response.toString();\n\t\t}\n\n\t\tif (isNodeExecutionData(response)) {\n\t\t\treturn JSON.stringify(\n\t\t\t\tresponse.map((item) => item.json),\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t);\n\t\t}\n\n\t\tif (isObject(response)) {\n\t\t\treturn JSON.stringify(response, null, 2);\n\t\t}\n\n\t\tif (typeof response !== 'string') {\n\t\t\tthrow new NodeOperationError(this.baseContext.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}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Executes specified sub-workflow with provided inputs\n\t */\n\tprivate async executeSubWorkflow(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tworkflowInfo: IExecuteWorkflowInfo,\n\t\titems: INodeExecutionData[],\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<{ response: IDataObject | INodeExecutionData[]; subExecutionId: string }> {\n\t\tlet receivedData: ExecuteWorkflowData;\n\t\ttry {\n\t\t\treceivedData = await context.executeWorkflow(workflowInfo, items, runManager?.getChild(), {\n\t\t\t\tparentExecution: {\n\t\t\t\t\texecutionId: workflowProxy.$execution.id,\n\t\t\t\t\tworkflowId: workflowProxy.$workflow.id,\n\t\t\t\t},\n\t\t\t});\n\t\t\t// Set sub-workflow execution id so it can be used in other places\n\t\t\tthis.subExecutionId = receivedData.executionId;\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(context.getNode(), error as Error);\n\t\t}\n\n\t\tlet response: IDataObject | INodeExecutionData[] | undefined;\n\t\tif (this.returnAllItems) {\n\t\t\tresponse = receivedData?.data?.[0]?.length ? receivedData.data[0] : undefined;\n\t\t} else {\n\t\t\tresponse = receivedData?.data?.[0]?.[0]?.json;\n\t\t}\n\t\tif (response === undefined) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'There was an error: \"The workflow did not return a response\"',\n\t\t\t);\n\t\t}\n\n\t\treturn { response, subExecutionId: receivedData.executionId };\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source and executes it.\n\t * This function will be called as part of the tool execution (from the toolHandler)\n\t */\n\tprivate async runFunction(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<IDataObject | INodeExecutionData[]> {\n\t\tconst source = context.getNodeParameter('source', itemIndex) as string;\n\t\tconst workflowProxy = context.getWorkflowDataProxy(0);\n\n\t\tconst { workflowInfo } = await this.getSubWorkflowInfo(\n\t\t\tcontext,\n\t\t\tsource,\n\t\t\titemIndex,\n\t\t\tworkflowProxy,\n\t\t);\n\t\tconst rawData = this.prepareRawData(context, query, itemIndex);\n\t\tconst items = await this.prepareWorkflowItems(context, query, itemIndex, rawData);\n\n\t\tthis.subWorkflowId = workflowInfo.id;\n\n\t\tconst { response } = await this.executeSubWorkflow(\n\t\t\tcontext,\n\t\t\tworkflowInfo,\n\t\t\titems,\n\t\t\tworkflowProxy,\n\t\t\trunManager,\n\t\t);\n\t\treturn response;\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source (database or parameter)\n\t */\n\tprivate async getSubWorkflowInfo(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tsource: string,\n\t\titemIndex: number,\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t): Promise<{\n\t\tworkflowInfo: IExecuteWorkflowInfo;\n\t\tsubWorkflowId: string;\n\t}> {\n\t\tconst workflowInfo: IExecuteWorkflowInfo = {};\n\t\tlet subWorkflowId: string;\n\n\t\tif (source === 'database') {\n\t\t\tconst { value } = context.getNodeParameter(\n\t\t\t\t'workflowId',\n\t\t\t\titemIndex,\n\t\t\t\t{},\n\t\t\t) as INodeParameterResourceLocator;\n\t\t\tworkflowInfo.id = value as string;\n\t\t\tsubWorkflowId = workflowInfo.id;\n\t\t} else if (source === 'parameter') {\n\t\t\tconst workflowJson = context.getNodeParameter('workflowJson', itemIndex) as string;\n\t\t\ttry {\n\t\t\t\tworkflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase;\n\t\t\t\t// subworkflow is same as parent workflow\n\t\t\t\tsubWorkflowId = workflowProxy.$workflow.id;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`The provided workflow is not valid JSON: \"${(error as Error).message}\"`,\n\t\t\t\t\t{ itemIndex },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn { workflowInfo, subWorkflowId: subWorkflowId! };\n\t}\n\n\tprivate prepareRawData(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t): IDataObject {\n\t\tconst rawData: IDataObject = { query };\n\t\tconst workflowFieldsJson = context.getNodeParameter('fields.values', itemIndex, [], {\n\t\t\trawExpressions: true,\n\t\t}) as SetField[];\n\n\t\t// Copied from Set Node v2\n\t\tfor (const entry of workflowFieldsJson) {\n\t\t\tif (entry.type === 'objectValue' && (entry.objectValue as string).startsWith('=')) {\n\t\t\t\trawData[entry.name] = (entry.objectValue as string).replace(/^=+/, '');\n\t\t\t}\n\t\t}\n\n\t\treturn rawData;\n\t}\n\n\t/**\n\t * Prepares the sub-workflow items for execution\n\t */\n\tprivate async prepareWorkflowItems(\n\t\tcontext: ISupplyDataFunctions | IExecuteFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trawData: IDataObject,\n\t): Promise<INodeExecutionData[]> {\n\t\tconst options: SetNodeOptions = { include: 'all' };\n\t\tlet jsonData = typeof query === 'object' ? query : { query };\n\n\t\tif (this.useSchema) {\n\t\t\tconst currentWorkflowInputs = getCurrentWorkflowInputData.call(context);\n\t\t\tjsonData = currentWorkflowInputs[itemIndex].json;\n\t\t}\n\n\t\tconst newItem = await manual.execute.call(\n\t\t\tcontext,\n\t\t\t{ json: jsonData },\n\t\t\titemIndex,\n\t\t\toptions,\n\t\t\trawData,\n\t\t\tcontext.getNode(),\n\t\t);\n\n\t\treturn [newItem] as INodeExecutionData[];\n\t}\n\n\t/**\n\t * Create structured tool by parsing the sub-workflow input schema\n\t */\n\tprivate async createStructuredTool(\n\t\tname: string,\n\t\tdescription: string,\n\t\tfunc: (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t) => Promise<string | IDataObject | IDataObject[]>,\n\t): Promise<DynamicStructuredTool | DynamicTool> {\n\t\tconst collectedArguments = await this.extractFromAIParameters();\n\n\t\t// If there are no `fromAI` arguments, fallback to creating a simple tool\n\t\tif (collectedArguments.length === 0) {\n\t\t\treturn new DynamicTool({ name, description, func });\n\t\t}\n\n\t\t// Otherwise, prepare Zod schema and create a structured tool\n\t\tconst schema = this.createZodSchema(collectedArguments);\n\t\treturn new DynamicStructuredTool({ schema, name, description, func });\n\t}\n\n\tprivate async extractFromAIParameters(): Promise<FromAIArgument[]> {\n\t\tconst collectedArguments: FromAIArgument[] = [];\n\t\ttraverseNodeParameters(this.baseContext.getNode().parameters, collectedArguments);\n\n\t\tconst uniqueArgsMap = new Map<string, FromAIArgument>();\n\t\tfor (const arg of collectedArguments) {\n\t\t\tuniqueArgsMap.set(arg.key, arg);\n\t\t}\n\n\t\treturn Array.from(uniqueArgsMap.values());\n\t}\n\n\tprivate createZodSchema(args: FromAIArgument[]): z.ZodObject<any> {\n\t\tconst schemaObj = args.reduce((acc: Record<string, z.ZodTypeAny>, placeholder) => {\n\t\t\tacc[placeholder.key] = generateZodSchema(placeholder);\n\t\t\treturn acc;\n\t\t}, {});\n\n\t\treturn z.object(schemaObj).required();\n\t}\n}\n"],"mappings":"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","names":["isArray","isObject"]}
@@ -22,6 +22,7 @@ __export(VectorStoreQdrant_node_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(VectorStoreQdrant_node_exports);
24
24
  var import_qdrant = require("@langchain/qdrant");
25
+ var import_n8n_workflow = require("n8n-workflow");
25
26
  var import_Qdrant = require("./Qdrant.utils");
26
27
  var import_createVectorStoreNode = require("../shared/createVectorStoreNode/createVectorStoreNode");
27
28
  var import_listSearch = require("../shared/createVectorStoreNode/methods/listSearch");
@@ -39,6 +40,22 @@ const _ExtendedQdrantVectorStore = class _ExtendedQdrantVectorStore extends impo
39
40
  _ExtendedQdrantVectorStore.defaultFilter = {};
40
41
  let ExtendedQdrantVectorStore = _ExtendedQdrantVectorStore;
41
42
  const sharedFields = [import_descriptions.qdrantCollectionRLC];
43
+ const sharedOptions = [
44
+ {
45
+ displayName: "Content Payload Key",
46
+ name: "contentPayloadKey",
47
+ type: "string",
48
+ default: "content",
49
+ description: 'The key to use for the content payload in Qdrant. Default is "content".'
50
+ },
51
+ {
52
+ displayName: "Metadata Payload Key",
53
+ name: "metadataPayloadKey",
54
+ type: "string",
55
+ default: "metadata",
56
+ description: 'The key to use for the metadata payload in Qdrant. Default is "metadata".'
57
+ }
58
+ ];
42
59
  const insertFields = [
43
60
  {
44
61
  displayName: "Options",
@@ -53,7 +70,8 @@ const insertFields = [
53
70
  type: "json",
54
71
  default: "",
55
72
  description: 'JSON options for creating a collection. <a href="https://qdrant.tech/documentation/concepts/collections">Learn more</a>.'
56
- }
73
+ },
74
+ ...sharedOptions
57
75
  ]
58
76
  }
59
77
  ];
@@ -75,7 +93,8 @@ const retrieveFields = [
75
93
  default: '{\n "should": [\n {\n "key": "metadata.batch",\n "match": {\n "value": 12345\n }\n }\n ]\n}',
76
94
  validateType: "object",
77
95
  description: 'Filter pageContent or metadata using this <a href="https://qdrant.tech/documentation/concepts/filtering/" target="_blank">filtering syntax</a>'
78
- }
96
+ },
97
+ ...sharedOptions
79
98
  ]
80
99
  }
81
100
  ];
@@ -102,11 +121,21 @@ class VectorStoreQdrant extends (0, import_createVectorStoreNode.createVectorSto
102
121
  const collection = context.getNodeParameter("qdrantCollection", itemIndex, "", {
103
122
  extractValue: true
104
123
  });
124
+ const contentPayloadKey = context.getNodeParameter("options.contentPayloadKey", itemIndex, "");
125
+ (0, import_n8n_workflow.assertParamIsString)("contentPayloadKey", contentPayloadKey, context.getNode());
126
+ const metadataPayloadKey = context.getNodeParameter(
127
+ "options.metadataPayloadKey",
128
+ itemIndex,
129
+ ""
130
+ );
131
+ (0, import_n8n_workflow.assertParamIsString)("metadataPayloadKey", metadataPayloadKey, context.getNode());
105
132
  const credentials = await context.getCredentials("qdrantApi");
106
133
  const client = (0, import_Qdrant.createQdrantClient)(credentials);
107
134
  const config = {
108
135
  client,
109
- collectionName: collection
136
+ collectionName: collection,
137
+ contentPayloadKey: contentPayloadKey !== "" ? contentPayloadKey : void 0,
138
+ metadataPayloadKey: metadataPayloadKey !== "" ? metadataPayloadKey : void 0
110
139
  };
111
140
  return await ExtendedQdrantVectorStore.fromExistingCollection(embeddings, config, filter);
112
141
  },
@@ -114,13 +143,23 @@ class VectorStoreQdrant extends (0, import_createVectorStoreNode.createVectorSto
114
143
  const collectionName = context.getNodeParameter("qdrantCollection", itemIndex, "", {
115
144
  extractValue: true
116
145
  });
146
+ const contentPayloadKey = context.getNodeParameter("options.contentPayloadKey", itemIndex, "");
147
+ (0, import_n8n_workflow.assertParamIsString)("contentPayloadKey", contentPayloadKey, context.getNode());
148
+ const metadataPayloadKey = context.getNodeParameter(
149
+ "options.metadataPayloadKey",
150
+ itemIndex,
151
+ ""
152
+ );
153
+ (0, import_n8n_workflow.assertParamIsString)("metadataPayloadKey", metadataPayloadKey, context.getNode());
117
154
  const { collectionConfig } = context.getNodeParameter("options", itemIndex, {});
118
155
  const credentials = await context.getCredentials("qdrantApi");
119
156
  const client = (0, import_Qdrant.createQdrantClient)(credentials);
120
157
  const config = {
121
158
  client,
122
159
  collectionName,
123
- collectionConfig
160
+ collectionConfig,
161
+ contentPayloadKey: contentPayloadKey !== "" ? contentPayloadKey : void 0,
162
+ metadataPayloadKey: metadataPayloadKey !== "" ? metadataPayloadKey : void 0
124
163
  };
125
164
  await import_qdrant.QdrantVectorStore.fromDocuments(documents, embeddings, config);
126
165
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.ts"],"sourcesContent":["import type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type { Embeddings } from '@langchain/core/embeddings';\nimport type { QdrantLibArgs } from '@langchain/qdrant';\nimport { QdrantVectorStore } from '@langchain/qdrant';\nimport { type Schemas as QdrantSchemas } from '@qdrant/js-client-rest';\nimport type { IDataObject, INodeProperties } from 'n8n-workflow';\n\nimport { createQdrantClient, type QdrantCredential } from './Qdrant.utils';\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\nimport { qdrantCollectionsSearch } from '../shared/createVectorStoreNode/methods/listSearch';\nimport { qdrantCollectionRLC } from '../shared/descriptions';\n\nclass ExtendedQdrantVectorStore extends QdrantVectorStore {\n\tprivate static defaultFilter: IDataObject = {};\n\n\tstatic async fromExistingCollection(\n\t\tembeddings: Embeddings,\n\t\targs: QdrantLibArgs,\n\t\tdefaultFilter: IDataObject = {},\n\t): Promise<QdrantVectorStore> {\n\t\tExtendedQdrantVectorStore.defaultFilter = defaultFilter;\n\t\treturn await super.fromExistingCollection(embeddings, args);\n\t}\n\n\tasync similaritySearch(query: string, k: number, filter?: IDataObject, callbacks?: Callbacks) {\n\t\tconst mergedFilter = { ...ExtendedQdrantVectorStore.defaultFilter, ...filter };\n\t\treturn await super.similaritySearch(query, k, mergedFilter, callbacks);\n\t}\n}\n\nconst sharedFields: INodeProperties[] = [qdrantCollectionRLC];\n\nconst insertFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Collection Config',\n\t\t\t\tname: 'collectionConfig',\n\t\t\t\ttype: 'json',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'JSON options for creating a collection. <a href=\"https://qdrant.tech/documentation/concepts/collections\">Learn more</a>.',\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst retrieveFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Search Filter',\n\t\t\t\tname: 'searchFilterJson',\n\t\t\t\ttype: 'json',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'{\\n \"should\": [\\n {\\n \"key\": \"metadata.batch\",\\n \"match\": {\\n \"value\": 12345\\n }\\n }\\n ]\\n}',\n\t\t\t\tvalidateType: 'object',\n\t\t\t\tdescription:\n\t\t\t\t\t'Filter pageContent or metadata using this <a href=\"https://qdrant.tech/documentation/concepts/filtering/\" target=\"_blank\">filtering syntax</a>',\n\t\t\t},\n\t\t],\n\t},\n];\n\nexport class VectorStoreQdrant extends createVectorStoreNode<ExtendedQdrantVectorStore>({\n\tmeta: {\n\t\tdisplayName: 'Qdrant Vector Store',\n\t\tname: 'vectorStoreQdrant',\n\t\tdescription: 'Work with your data in a Qdrant collection',\n\t\ticon: 'file:qdrant.svg',\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreqdrant/',\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'qdrantApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t},\n\tmethods: { listSearch: { qdrantCollectionsSearch } },\n\tloadFields: retrieveFields,\n\tinsertFields,\n\tsharedFields,\n\tretrieveFields,\n\tasync getVectorStoreClient(context, filter, embeddings, itemIndex) {\n\t\tconst collection = context.getNodeParameter('qdrantCollection', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\tconst credentials = await context.getCredentials('qdrantApi');\n\n\t\tconst client = createQdrantClient(credentials as QdrantCredential);\n\n\t\tconst config: QdrantLibArgs = {\n\t\t\tclient,\n\t\t\tcollectionName: collection,\n\t\t};\n\n\t\treturn await ExtendedQdrantVectorStore.fromExistingCollection(embeddings, config, filter);\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\tconst collectionName = context.getNodeParameter('qdrantCollection', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\t// If collection config is not provided, the collection will be created with default settings\n\t\t// i.e. with the size of the passed embeddings and \"Cosine\" distance metric\n\t\tconst { collectionConfig } = context.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tcollectionConfig?: QdrantSchemas['CreateCollection'];\n\t\t};\n\t\tconst credentials = await context.getCredentials('qdrantApi');\n\n\t\tconst client = createQdrantClient(credentials as QdrantCredential);\n\n\t\tconst config: QdrantLibArgs = {\n\t\t\tclient,\n\t\t\tcollectionName,\n\t\t\tcollectionConfig,\n\t\t};\n\n\t\tawait QdrantVectorStore.fromDocuments(documents, embeddings, config);\n\t},\n}) {}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAAkC;AAIlC,oBAA0D;AAC1D,mCAAsC;AACtC,wBAAwC;AACxC,0BAAoC;AAEpC,MAAM,6BAAN,MAAM,mCAAkC,gCAAkB;AAAA,EAGzD,aAAa,uBACZ,YACA,MACA,gBAA6B,CAAC,GACD;AAC7B,+BAA0B,gBAAgB;AAC1C,WAAO,MAAM,MAAM,uBAAuB,YAAY,IAAI;AAAA,EAC3D;AAAA,EAEA,MAAM,iBAAiB,OAAe,GAAW,QAAsB,WAAuB;AAC7F,UAAM,eAAe,EAAE,GAAG,2BAA0B,eAAe,GAAG,OAAO;AAC7E,WAAO,MAAM,MAAM,iBAAiB,OAAO,GAAG,cAAc,SAAS;AAAA,EACtE;AACD;AAhBM,2BACU,gBAA6B,CAAC;AAD9C,IAAM,4BAAN;AAkBA,MAAM,eAAkC,CAAC,uCAAmB;AAE5D,MAAM,eAAkC;AAAA,EACvC;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC;AAAA,IACV,SAAS;AAAA,MACR;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AACD;AAEA,MAAM,iBAAoC;AAAA,EACzC;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS,CAAC;AAAA,IACV,SAAS;AAAA,MACR;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,UACZ,MAAM;AAAA,QACP;AAAA,QACA,SACC;AAAA,QACD,cAAc;AAAA,QACd,aACC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AACD;AAEO,MAAM,8BAA0B,oDAAiD;AAAA,EACvF,MAAM;AAAA,IACL,aAAa;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,SACC;AAAA,IACD,aAAa;AAAA,MACZ;AAAA,QACC,MAAM;AAAA,QACN,UAAU;AAAA,MACX;AAAA,IACD;AAAA,EACD;AAAA,EACA,SAAS,EAAE,YAAY,EAAE,mEAAwB,EAAE;AAAA,EACnD,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM,qBAAqB,SAAS,QAAQ,YAAY,WAAW;AAClE,UAAM,aAAa,QAAQ,iBAAiB,oBAAoB,WAAW,IAAI;AAAA,MAC9E,cAAc;AAAA,IACf,CAAC;AAED,UAAM,cAAc,MAAM,QAAQ,eAAe,WAAW;AAE5D,UAAM,aAAS,kCAAmB,WAA+B;AAEjE,UAAM,SAAwB;AAAA,MAC7B;AAAA,MACA,gBAAgB;AAAA,IACjB;AAEA,WAAO,MAAM,0BAA0B,uBAAuB,YAAY,QAAQ,MAAM;AAAA,EACzF;AAAA,EACA,MAAM,oBAAoB,SAAS,YAAY,WAAW,WAAW;AACpE,UAAM,iBAAiB,QAAQ,iBAAiB,oBAAoB,WAAW,IAAI;AAAA,MAClF,cAAc;AAAA,IACf,CAAC;AAID,UAAM,EAAE,iBAAiB,IAAI,QAAQ,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAG9E,UAAM,cAAc,MAAM,QAAQ,eAAe,WAAW;AAE5D,UAAM,aAAS,kCAAmB,WAA+B;AAEjE,UAAM,SAAwB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,UAAM,gCAAkB,cAAc,WAAW,YAAY,MAAM;AAAA,EACpE;AACD,CAAC,EAAE;AAAC;","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.ts"],"sourcesContent":["import type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type { Embeddings } from '@langchain/core/embeddings';\nimport type { QdrantLibArgs } from '@langchain/qdrant';\nimport { QdrantVectorStore } from '@langchain/qdrant';\nimport { type Schemas as QdrantSchemas } from '@qdrant/js-client-rest';\nimport { assertParamIsString, type IDataObject, type INodeProperties } from 'n8n-workflow';\n\nimport { createQdrantClient, type QdrantCredential } from './Qdrant.utils';\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\nimport { qdrantCollectionsSearch } from '../shared/createVectorStoreNode/methods/listSearch';\nimport { qdrantCollectionRLC } from '../shared/descriptions';\n\nclass ExtendedQdrantVectorStore extends QdrantVectorStore {\n\tprivate static defaultFilter: IDataObject = {};\n\n\tstatic async fromExistingCollection(\n\t\tembeddings: Embeddings,\n\t\targs: QdrantLibArgs,\n\t\tdefaultFilter: IDataObject = {},\n\t): Promise<QdrantVectorStore> {\n\t\tExtendedQdrantVectorStore.defaultFilter = defaultFilter;\n\t\treturn await super.fromExistingCollection(embeddings, args);\n\t}\n\n\tasync similaritySearch(query: string, k: number, filter?: IDataObject, callbacks?: Callbacks) {\n\t\tconst mergedFilter = { ...ExtendedQdrantVectorStore.defaultFilter, ...filter };\n\t\treturn await super.similaritySearch(query, k, mergedFilter, callbacks);\n\t}\n}\n\nconst sharedFields: INodeProperties[] = [qdrantCollectionRLC];\n\nconst sharedOptions: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Content Payload Key',\n\t\tname: 'contentPayloadKey',\n\t\ttype: 'string',\n\t\tdefault: 'content',\n\t\tdescription: 'The key to use for the content payload in Qdrant. Default is \"content\".',\n\t},\n\t{\n\t\tdisplayName: 'Metadata Payload Key',\n\t\tname: 'metadataPayloadKey',\n\t\ttype: 'string',\n\t\tdefault: 'metadata',\n\t\tdescription: 'The key to use for the metadata payload in Qdrant. Default is \"metadata\".',\n\t},\n];\n\nconst insertFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Collection Config',\n\t\t\t\tname: 'collectionConfig',\n\t\t\t\ttype: 'json',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'JSON options for creating a collection. <a href=\"https://qdrant.tech/documentation/concepts/collections\">Learn more</a>.',\n\t\t\t},\n\t\t\t...sharedOptions,\n\t\t],\n\t},\n];\n\nconst retrieveFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Search Filter',\n\t\t\t\tname: 'searchFilterJson',\n\t\t\t\ttype: 'json',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdefault:\n\t\t\t\t\t'{\\n \"should\": [\\n {\\n \"key\": \"metadata.batch\",\\n \"match\": {\\n \"value\": 12345\\n }\\n }\\n ]\\n}',\n\t\t\t\tvalidateType: 'object',\n\t\t\t\tdescription:\n\t\t\t\t\t'Filter pageContent or metadata using this <a href=\"https://qdrant.tech/documentation/concepts/filtering/\" target=\"_blank\">filtering syntax</a>',\n\t\t\t},\n\t\t\t...sharedOptions,\n\t\t],\n\t},\n];\n\nexport class VectorStoreQdrant extends createVectorStoreNode<ExtendedQdrantVectorStore>({\n\tmeta: {\n\t\tdisplayName: 'Qdrant Vector Store',\n\t\tname: 'vectorStoreQdrant',\n\t\tdescription: 'Work with your data in a Qdrant collection',\n\t\ticon: 'file:qdrant.svg',\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreqdrant/',\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'qdrantApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t},\n\tmethods: { listSearch: { qdrantCollectionsSearch } },\n\tloadFields: retrieveFields,\n\tinsertFields,\n\tsharedFields,\n\tretrieveFields,\n\tasync getVectorStoreClient(context, filter, embeddings, itemIndex) {\n\t\tconst collection = context.getNodeParameter('qdrantCollection', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\tconst contentPayloadKey = context.getNodeParameter('options.contentPayloadKey', itemIndex, '');\n\t\tassertParamIsString('contentPayloadKey', contentPayloadKey, context.getNode());\n\n\t\tconst metadataPayloadKey = context.getNodeParameter(\n\t\t\t'options.metadataPayloadKey',\n\t\t\titemIndex,\n\t\t\t'',\n\t\t);\n\t\tassertParamIsString('metadataPayloadKey', metadataPayloadKey, context.getNode());\n\n\t\tconst credentials = await context.getCredentials('qdrantApi');\n\n\t\tconst client = createQdrantClient(credentials as QdrantCredential);\n\n\t\tconst config: QdrantLibArgs = {\n\t\t\tclient,\n\t\t\tcollectionName: collection,\n\t\t\tcontentPayloadKey: contentPayloadKey !== '' ? contentPayloadKey : undefined,\n\t\t\tmetadataPayloadKey: metadataPayloadKey !== '' ? metadataPayloadKey : undefined,\n\t\t};\n\n\t\treturn await ExtendedQdrantVectorStore.fromExistingCollection(embeddings, config, filter);\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\tconst collectionName = context.getNodeParameter('qdrantCollection', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\tconst contentPayloadKey = context.getNodeParameter('options.contentPayloadKey', itemIndex, '');\n\t\tassertParamIsString('contentPayloadKey', contentPayloadKey, context.getNode());\n\n\t\tconst metadataPayloadKey = context.getNodeParameter(\n\t\t\t'options.metadataPayloadKey',\n\t\t\titemIndex,\n\t\t\t'',\n\t\t);\n\t\tassertParamIsString('metadataPayloadKey', metadataPayloadKey, context.getNode());\n\n\t\t// If collection config is not provided, the collection will be created with default settings\n\t\t// i.e. with the size of the passed embeddings and \"Cosine\" distance metric\n\t\tconst { collectionConfig } = context.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tcollectionConfig?: QdrantSchemas['CreateCollection'];\n\t\t};\n\t\tconst credentials = await context.getCredentials('qdrantApi');\n\n\t\tconst client = createQdrantClient(credentials as QdrantCredential);\n\n\t\tconst config: QdrantLibArgs = {\n\t\t\tclient,\n\t\t\tcollectionName,\n\t\t\tcollectionConfig,\n\t\t\tcontentPayloadKey: contentPayloadKey !== '' ? contentPayloadKey : undefined,\n\t\t\tmetadataPayloadKey: metadataPayloadKey !== '' ? metadataPayloadKey : undefined,\n\t\t};\n\n\t\tawait QdrantVectorStore.fromDocuments(documents, embeddings, config);\n\t},\n}) {}\n"],"mappings":"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","names":[]}