@n8n/n8n-nodes-langchain 1.101.2 → 1.103.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 (174) hide show
  1. package/dist/credentials/CohereApi.credentials.js +7 -1
  2. package/dist/credentials/CohereApi.credentials.js.map +1 -1
  3. package/dist/known/credentials.json +3 -0
  4. package/dist/known/nodes.json +16 -0
  5. package/dist/nodes/agents/Agent/Agent.node.js +1 -0
  6. package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
  7. package/dist/nodes/agents/Agent/AgentTool.node.js +57 -0
  8. package/dist/nodes/agents/Agent/AgentTool.node.js.map +1 -0
  9. package/dist/nodes/agents/Agent/V2/AgentToolV2.node.js +104 -0
  10. package/dist/nodes/agents/Agent/V2/AgentToolV2.node.js.map +1 -0
  11. package/dist/nodes/agents/Agent/V2/AgentV2.node.js +4 -66
  12. package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -1
  13. package/dist/nodes/agents/Agent/V2/utils.js +92 -0
  14. package/dist/nodes/agents/Agent/V2/utils.js.map +1 -0
  15. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js +13 -10
  16. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js.map +1 -1
  17. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +14 -7
  18. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
  19. package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -1
  20. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +1 -1
  21. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
  22. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js +13 -2
  23. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js.map +1 -1
  24. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +2 -2
  25. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
  26. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js +2 -0
  27. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js.map +1 -1
  28. package/dist/nodes/llms/LmChatCohere/LmChatCohere.node.js +181 -0
  29. package/dist/nodes/llms/LmChatCohere/LmChatCohere.node.js.map +1 -0
  30. package/dist/nodes/llms/LmChatCohere/cohere.dark.svg +5 -0
  31. package/dist/nodes/llms/LmChatCohere/cohere.svg +5 -0
  32. package/dist/nodes/llms/N8nLlmTracing.js +4 -4
  33. package/dist/nodes/llms/N8nLlmTracing.js.map +1 -1
  34. package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +55 -5
  35. package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
  36. package/dist/nodes/mcp/McpClientTool/loadOptions.js +11 -2
  37. package/dist/nodes/mcp/McpClientTool/loadOptions.js.map +1 -1
  38. package/dist/nodes/mcp/McpClientTool/types.js.map +1 -1
  39. package/dist/nodes/mcp/McpClientTool/utils.js +21 -11
  40. package/dist/nodes/mcp/McpClientTool/utils.js.map +1 -1
  41. package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js +1 -1
  42. package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js.map +1 -1
  43. package/dist/nodes/tools/ToolCode/ToolCode.node.js +1 -2
  44. package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
  45. package/dist/nodes/tools/ToolThink/ToolThink.node.js +5 -2
  46. package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
  47. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +1 -2
  48. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
  49. package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +2 -2
  50. package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
  51. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +2 -1
  52. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
  53. package/dist/nodes/trigger/ChatTrigger/templates.js +3 -1
  54. package/dist/nodes/trigger/ChatTrigger/templates.js.map +1 -1
  55. package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js +2 -1
  56. package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js.map +1 -1
  57. package/dist/nodes/vendors/Anthropic/Anthropic.node.js +42 -0
  58. package/dist/nodes/vendors/Anthropic/Anthropic.node.js.map +1 -0
  59. package/dist/nodes/vendors/Anthropic/actions/descriptions.js +52 -0
  60. package/dist/nodes/vendors/Anthropic/actions/descriptions.js.map +1 -0
  61. package/dist/nodes/vendors/Anthropic/actions/document/analyze.operation.js +125 -0
  62. package/dist/nodes/vendors/Anthropic/actions/document/analyze.operation.js.map +1 -0
  63. package/dist/nodes/vendors/Anthropic/actions/document/index.js +64 -0
  64. package/dist/nodes/vendors/Anthropic/actions/document/index.js.map +1 -0
  65. package/dist/nodes/vendors/Anthropic/actions/file/delete.operation.js +61 -0
  66. package/dist/nodes/vendors/Anthropic/actions/file/delete.operation.js.map +1 -0
  67. package/dist/nodes/vendors/Anthropic/actions/file/get.operation.js +63 -0
  68. package/dist/nodes/vendors/Anthropic/actions/file/get.operation.js.map +1 -0
  69. package/dist/nodes/vendors/Anthropic/actions/file/index.js +94 -0
  70. package/dist/nodes/vendors/Anthropic/actions/file/index.js.map +1 -0
  71. package/dist/nodes/vendors/Anthropic/actions/file/list.operation.js +108 -0
  72. package/dist/nodes/vendors/Anthropic/actions/file/list.operation.js.map +1 -0
  73. package/dist/nodes/vendors/Anthropic/actions/file/upload.operation.js +126 -0
  74. package/dist/nodes/vendors/Anthropic/actions/file/upload.operation.js.map +1 -0
  75. package/dist/nodes/vendors/Anthropic/actions/image/analyze.operation.js +125 -0
  76. package/dist/nodes/vendors/Anthropic/actions/image/analyze.operation.js.map +1 -0
  77. package/dist/nodes/vendors/Anthropic/actions/image/index.js +64 -0
  78. package/dist/nodes/vendors/Anthropic/actions/image/index.js.map +1 -0
  79. package/dist/nodes/vendors/Anthropic/actions/node.type.js +17 -0
  80. package/dist/nodes/vendors/Anthropic/actions/node.type.js.map +1 -0
  81. package/dist/nodes/vendors/Anthropic/actions/prompt/generate.operation.js +87 -0
  82. package/dist/nodes/vendors/Anthropic/actions/prompt/generate.operation.js.map +1 -0
  83. package/dist/nodes/vendors/Anthropic/actions/prompt/improve.operation.js +154 -0
  84. package/dist/nodes/vendors/Anthropic/actions/prompt/improve.operation.js.map +1 -0
  85. package/dist/nodes/vendors/Anthropic/actions/prompt/index.js +95 -0
  86. package/dist/nodes/vendors/Anthropic/actions/prompt/index.js.map +1 -0
  87. package/dist/nodes/vendors/Anthropic/actions/prompt/templatize.operation.js +146 -0
  88. package/dist/nodes/vendors/Anthropic/actions/prompt/templatize.operation.js.map +1 -0
  89. package/dist/nodes/vendors/Anthropic/actions/router.js +93 -0
  90. package/dist/nodes/vendors/Anthropic/actions/router.js.map +1 -0
  91. package/dist/nodes/vendors/Anthropic/actions/text/index.js +64 -0
  92. package/dist/nodes/vendors/Anthropic/actions/text/index.js.map +1 -0
  93. package/dist/nodes/vendors/Anthropic/actions/text/message.operation.js +540 -0
  94. package/dist/nodes/vendors/Anthropic/actions/text/message.operation.js.map +1 -0
  95. package/dist/nodes/vendors/Anthropic/actions/versionDescription.js +125 -0
  96. package/dist/nodes/vendors/Anthropic/actions/versionDescription.js.map +1 -0
  97. package/dist/nodes/vendors/Anthropic/anthropic.svg +1 -0
  98. package/dist/nodes/vendors/Anthropic/helpers/baseAnalyze.js +109 -0
  99. package/dist/nodes/vendors/Anthropic/helpers/baseAnalyze.js.map +1 -0
  100. package/dist/nodes/vendors/Anthropic/helpers/interfaces.js +17 -0
  101. package/dist/nodes/vendors/Anthropic/helpers/interfaces.js.map +1 -0
  102. package/dist/nodes/vendors/Anthropic/helpers/utils.js +84 -0
  103. package/dist/nodes/vendors/Anthropic/helpers/utils.js.map +1 -0
  104. package/dist/nodes/vendors/Anthropic/methods/index.js +39 -0
  105. package/dist/nodes/vendors/Anthropic/methods/index.js.map +1 -0
  106. package/dist/nodes/vendors/Anthropic/methods/listSearch.js +42 -0
  107. package/dist/nodes/vendors/Anthropic/methods/listSearch.js.map +1 -0
  108. package/dist/nodes/vendors/Anthropic/transport/index.js +57 -0
  109. package/dist/nodes/vendors/Anthropic/transport/index.js.map +1 -0
  110. package/dist/nodes/vendors/GoogleGemini/GoogleGemini.node.js +42 -0
  111. package/dist/nodes/vendors/GoogleGemini/GoogleGemini.node.js.map +1 -0
  112. package/dist/nodes/vendors/GoogleGemini/actions/audio/analyze.operation.js +125 -0
  113. package/dist/nodes/vendors/GoogleGemini/actions/audio/analyze.operation.js.map +1 -0
  114. package/dist/nodes/vendors/GoogleGemini/actions/audio/index.js +74 -0
  115. package/dist/nodes/vendors/GoogleGemini/actions/audio/index.js.map +1 -0
  116. package/dist/nodes/vendors/GoogleGemini/actions/audio/transcribe.operation.js +184 -0
  117. package/dist/nodes/vendors/GoogleGemini/actions/audio/transcribe.operation.js.map +1 -0
  118. package/dist/nodes/vendors/GoogleGemini/actions/descriptions.js +52 -0
  119. package/dist/nodes/vendors/GoogleGemini/actions/descriptions.js.map +1 -0
  120. package/dist/nodes/vendors/GoogleGemini/actions/document/analyze.operation.js +125 -0
  121. package/dist/nodes/vendors/GoogleGemini/actions/document/analyze.operation.js.map +1 -0
  122. package/dist/nodes/vendors/GoogleGemini/actions/document/index.js +64 -0
  123. package/dist/nodes/vendors/GoogleGemini/actions/document/index.js.map +1 -0
  124. package/dist/nodes/vendors/GoogleGemini/actions/file/index.js +64 -0
  125. package/dist/nodes/vendors/GoogleGemini/actions/file/index.js.map +1 -0
  126. package/dist/nodes/vendors/GoogleGemini/actions/file/upload.operation.js +119 -0
  127. package/dist/nodes/vendors/GoogleGemini/actions/file/upload.operation.js.map +1 -0
  128. package/dist/nodes/vendors/GoogleGemini/actions/image/analyze.operation.js +125 -0
  129. package/dist/nodes/vendors/GoogleGemini/actions/image/analyze.operation.js.map +1 -0
  130. package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js +167 -0
  131. package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js.map +1 -0
  132. package/dist/nodes/vendors/GoogleGemini/actions/image/index.js +74 -0
  133. package/dist/nodes/vendors/GoogleGemini/actions/image/index.js.map +1 -0
  134. package/dist/nodes/vendors/GoogleGemini/actions/node.type.js +17 -0
  135. package/dist/nodes/vendors/GoogleGemini/actions/node.type.js.map +1 -0
  136. package/dist/nodes/vendors/GoogleGemini/actions/router.js +97 -0
  137. package/dist/nodes/vendors/GoogleGemini/actions/router.js.map +1 -0
  138. package/dist/nodes/vendors/GoogleGemini/actions/text/index.js +64 -0
  139. package/dist/nodes/vendors/GoogleGemini/actions/text/index.js.map +1 -0
  140. package/dist/nodes/vendors/GoogleGemini/actions/text/message.operation.js +339 -0
  141. package/dist/nodes/vendors/GoogleGemini/actions/text/message.operation.js.map +1 -0
  142. package/dist/nodes/vendors/GoogleGemini/actions/versionDescription.js +131 -0
  143. package/dist/nodes/vendors/GoogleGemini/actions/versionDescription.js.map +1 -0
  144. package/dist/nodes/vendors/GoogleGemini/actions/video/analyze.operation.js +125 -0
  145. package/dist/nodes/vendors/GoogleGemini/actions/video/analyze.operation.js.map +1 -0
  146. package/dist/nodes/vendors/GoogleGemini/actions/video/download.operation.js +88 -0
  147. package/dist/nodes/vendors/GoogleGemini/actions/video/download.operation.js.map +1 -0
  148. package/dist/nodes/vendors/GoogleGemini/actions/video/generate.operation.js +228 -0
  149. package/dist/nodes/vendors/GoogleGemini/actions/video/generate.operation.js.map +1 -0
  150. package/dist/nodes/vendors/GoogleGemini/actions/video/index.js +84 -0
  151. package/dist/nodes/vendors/GoogleGemini/actions/video/index.js.map +1 -0
  152. package/dist/nodes/vendors/GoogleGemini/gemini.svg +1 -0
  153. package/dist/nodes/vendors/GoogleGemini/helpers/baseAnalyze.js +100 -0
  154. package/dist/nodes/vendors/GoogleGemini/helpers/baseAnalyze.js.map +1 -0
  155. package/dist/nodes/vendors/GoogleGemini/helpers/interfaces.js +17 -0
  156. package/dist/nodes/vendors/GoogleGemini/helpers/interfaces.js.map +1 -0
  157. package/dist/nodes/vendors/GoogleGemini/helpers/utils.js +91 -0
  158. package/dist/nodes/vendors/GoogleGemini/helpers/utils.js.map +1 -0
  159. package/dist/nodes/vendors/GoogleGemini/methods/index.js +39 -0
  160. package/dist/nodes/vendors/GoogleGemini/methods/index.js.map +1 -0
  161. package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js +74 -0
  162. package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js.map +1 -0
  163. package/dist/nodes/vendors/GoogleGemini/transport/index.js +48 -0
  164. package/dist/nodes/vendors/GoogleGemini/transport/index.js.map +1 -0
  165. package/dist/nodes/vendors/OpenAi/actions/router.js +1 -1
  166. package/dist/nodes/vendors/OpenAi/actions/router.js.map +1 -1
  167. package/dist/types/credentials.json +3 -3
  168. package/dist/types/nodes.json +9 -5
  169. package/dist/utils/descriptions.js +13 -2
  170. package/dist/utils/descriptions.js.map +1 -1
  171. package/dist/utils/helpers.js +2 -7
  172. package/dist/utils/helpers.js.map +1 -1
  173. package/dist/utils/output_parsers/N8nOutputParser.js.map +1 -1
  174. package/package.json +11 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.ts"],"sourcesContent":["import { ChatBedrockConverse } from '@langchain/aws';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatAwsBedrock implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'AWS Bedrock Chat Model',\n\n\t\tname: 'lmChatAwsBedrock',\n\t\ticon: 'file:bedrock.svg',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Language Model AWS Bedrock',\n\t\tdefaults: {\n\t\t\tname: 'AWS Bedrock 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.lmchatawsbedrock/',\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: 'aws',\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://bedrock.{{$credentials?.region ?? \"eu-central-1\"}}.amazonaws.com',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiChain]),\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.aws.amazon.com/bedrock/latest/userguide/foundation-models.html\">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: '/foundation-models?&byOutputModality=TEXT&byInferenceType=ON_DEMAND',\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: 'modelSummaries',\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.modelName}}',\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.modelArn}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.modelId}}',\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: '',\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: 'maxTokensToSample',\n\t\t\t\t\t\tdefault: 2000,\n\t\t\t\t\t\tdescription: 'The maximum number of tokens to generate in the completion',\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: '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],\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('aws');\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\ttemperature: number;\n\t\t\tmaxTokensToSample: number;\n\t\t};\n\n\t\tconst model = new ChatBedrockConverse({\n\t\t\tregion: credentials.region as string,\n\t\t\tmodel: modelName,\n\t\t\ttemperature: options.temperature,\n\t\t\tmaxTokens: options.maxTokensToSample,\n\t\t\tclientConfig: {\n\t\t\t\thttpAgent: getProxyAgent(),\n\t\t\t},\n\t\t\tcredentials: {\n\t\t\t\tsecretAccessKey: credentials.secretAccessKey as string,\n\t\t\t\taccessKeyId: credentials.accessKeyId as string,\n\t\t\t\tsessionToken: credentials.sessionToken as string,\n\t\t\t},\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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoC;AACpC,0BAMO;AAEP,4BAA8B;AAC9B,0BAA6C;AAE7C,wCAA+C;AAC/C,2BAA8B;AAEvB,MAAM,iBAAsC;AAAA,EAA5C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MAEb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,mBAAmB,YAAY;AAAA,UACpC,mBAAmB,CAAC,2BAA2B;AAAA,QAChD;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,QAAQ,CAAC;AAAA,MAET,SAAS,CAAC,wCAAoB,eAAe;AAAA,MAC7C,aAAa,CAAC,OAAO;AAAA,MACrB,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,iBAAiB;AAAA,QAChB,wBAAwB;AAAA,QACxB,SAAS;AAAA,MACV;AAAA,MACA,YAAY;AAAA,YACX,kDAA6B,CAAC,wCAAoB,SAAS,wCAAoB,OAAO,CAAC;AAAA,QACvF;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aACC;AAAA,UACD,aAAa;AAAA,YACZ,aAAa;AAAA,cACZ,SAAS;AAAA,gBACR,SAAS;AAAA,kBACR,QAAQ;AAAA,kBACR,KAAK;AAAA,gBACN;AAAA,gBACA,QAAQ;AAAA,kBACP,aAAa;AAAA,oBACZ;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,UAAU;AAAA,sBACX;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,MAAM;AAAA,wBACN,aAAa;AAAA,wBACb,OAAO;AAAA,sBACR;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,KAAK;AAAA,sBACN;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,UACA,SAAS;AAAA,YACR,MAAM;AAAA,cACL,MAAM;AAAA,cACN,UAAU;AAAA,YACX;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,EAAE;AAAA,cAC5D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,cAAc,MAAM,KAAK,eAAe,KAAK;AACnD,UAAM,YAAY,KAAK,iBAAiB,SAAS,SAAS;AAC1D,UAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAK9D,UAAM,QAAQ,IAAI,+BAAoB;AAAA,MACrC,QAAQ,YAAY;AAAA,MACpB,OAAO;AAAA,MACP,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,cAAc;AAAA,QACb,eAAW,qCAAc;AAAA,MAC1B;AAAA,MACA,aAAa;AAAA,QACZ,iBAAiB,YAAY;AAAA,QAC7B,aAAa,YAAY;AAAA,QACzB,cAAc,YAAY;AAAA,MAC3B;AAAA,MACA,WAAW,CAAC,IAAI,mCAAc,IAAI,CAAC;AAAA,MACnC,qBAAiB,kEAA+B,IAAI;AAAA,IACrD,CAAC;AAED,WAAO;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.ts"],"sourcesContent":["import { ChatBedrockConverse } from '@langchain/aws';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatAwsBedrock implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'AWS Bedrock Chat Model',\n\n\t\tname: 'lmChatAwsBedrock',\n\t\ticon: 'file:bedrock.svg',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Language Model AWS Bedrock',\n\t\tdefaults: {\n\t\t\tname: 'AWS Bedrock 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.lmchatawsbedrock/',\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: 'aws',\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://bedrock.{{$credentials?.region ?? \"eu-central-1\"}}.amazonaws.com',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiChain]),\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\tallowArbitraryValues: true, // Hide issues when model name is specified in the expression and does not match any of the options\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will generate the completion. <a href=\"https://docs.aws.amazon.com/bedrock/latest/userguide/foundation-models.html\">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: '/foundation-models?&byOutputModality=TEXT&byInferenceType=ON_DEMAND',\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: 'modelSummaries',\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.modelName}}',\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.modelArn}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.modelId}}',\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: '',\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: 'maxTokensToSample',\n\t\t\t\t\t\tdefault: 2000,\n\t\t\t\t\t\tdescription: 'The maximum number of tokens to generate in the completion',\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: '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],\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('aws');\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\ttemperature: number;\n\t\t\tmaxTokensToSample: number;\n\t\t};\n\n\t\tconst model = new ChatBedrockConverse({\n\t\t\tregion: credentials.region as string,\n\t\t\tmodel: modelName,\n\t\t\ttemperature: options.temperature,\n\t\t\tmaxTokens: options.maxTokensToSample,\n\t\t\tclientConfig: {\n\t\t\t\thttpAgent: getProxyAgent(),\n\t\t\t},\n\t\t\tcredentials: {\n\t\t\t\tsecretAccessKey: credentials.secretAccessKey as string,\n\t\t\t\taccessKeyId: credentials.accessKeyId as string,\n\t\t\t\tsessionToken: credentials.sessionToken as string,\n\t\t\t},\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":[]}
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var LmChatCohere_node_exports = {};
20
+ __export(LmChatCohere_node_exports, {
21
+ LmChatCohere: () => LmChatCohere,
22
+ tokensUsageParser: () => tokensUsageParser
23
+ });
24
+ module.exports = __toCommonJS(LmChatCohere_node_exports);
25
+ var import_cohere = require("@langchain/cohere");
26
+ var import_sharedFields = require("../../../utils/sharedFields");
27
+ var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler");
28
+ var import_N8nLlmTracing = require("../N8nLlmTracing");
29
+ function tokensUsageParser(result) {
30
+ let totalInputTokens = 0;
31
+ let totalOutputTokens = 0;
32
+ result.generations?.forEach((generationArray) => {
33
+ generationArray.forEach((gen) => {
34
+ const inputTokens = gen.generationInfo?.meta?.tokens?.inputTokens ?? 0;
35
+ const outputTokens = gen.generationInfo?.meta?.tokens?.outputTokens ?? 0;
36
+ totalInputTokens += inputTokens;
37
+ totalOutputTokens += outputTokens;
38
+ });
39
+ });
40
+ return {
41
+ completionTokens: totalOutputTokens,
42
+ promptTokens: totalInputTokens,
43
+ totalTokens: totalInputTokens + totalOutputTokens
44
+ };
45
+ }
46
+ class LmChatCohere {
47
+ constructor() {
48
+ this.description = {
49
+ displayName: "Cohere Chat Model",
50
+ name: "lmChatCohere",
51
+ icon: { light: "file:cohere.svg", dark: "file:cohere.dark.svg" },
52
+ group: ["transform"],
53
+ version: [1],
54
+ description: "For advanced usage with an AI chain",
55
+ defaults: {
56
+ name: "Cohere Chat Model"
57
+ },
58
+ codex: {
59
+ categories: ["AI"],
60
+ subcategories: {
61
+ AI: ["Language Models", "Root Nodes"],
62
+ "Language Models": ["Chat Models (Recommended)"]
63
+ },
64
+ resources: {
65
+ primaryDocumentation: [
66
+ {
67
+ url: "https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatcohere/"
68
+ }
69
+ ]
70
+ }
71
+ },
72
+ inputs: [],
73
+ outputs: ["ai_languageModel"],
74
+ outputNames: ["Model"],
75
+ credentials: [
76
+ {
77
+ name: "cohereApi",
78
+ required: true
79
+ }
80
+ ],
81
+ requestDefaults: {
82
+ baseURL: "={{$credentials?.url}}",
83
+ headers: {
84
+ accept: "application/json",
85
+ authorization: "=Bearer {{$credentials?.apiKey}}"
86
+ }
87
+ },
88
+ properties: [
89
+ (0, import_sharedFields.getConnectionHintNoticeField)(["ai_chain", "ai_agent"]),
90
+ {
91
+ displayName: "Model",
92
+ name: "model",
93
+ type: "options",
94
+ description: 'The model which will generate the completion. <a href="https://docs.cohere.com/docs/models">Learn more</a>.',
95
+ typeOptions: {
96
+ loadOptions: {
97
+ routing: {
98
+ request: {
99
+ method: "GET",
100
+ url: "/v1/models?page_size=100&endpoint=chat"
101
+ },
102
+ output: {
103
+ postReceive: [
104
+ {
105
+ type: "rootProperty",
106
+ properties: {
107
+ property: "models"
108
+ }
109
+ },
110
+ {
111
+ type: "setKeyValue",
112
+ properties: {
113
+ name: "={{$responseItem.name}}",
114
+ value: "={{$responseItem.name}}",
115
+ description: "={{$responseItem.description}}"
116
+ }
117
+ },
118
+ {
119
+ type: "sort",
120
+ properties: {
121
+ key: "name"
122
+ }
123
+ }
124
+ ]
125
+ }
126
+ }
127
+ }
128
+ },
129
+ default: "command-a-03-2025"
130
+ },
131
+ {
132
+ displayName: "Options",
133
+ name: "options",
134
+ placeholder: "Add Option",
135
+ description: "Additional options to add",
136
+ type: "collection",
137
+ default: {},
138
+ options: [
139
+ {
140
+ displayName: "Sampling Temperature",
141
+ name: "temperature",
142
+ default: 0.7,
143
+ typeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },
144
+ description: "Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.",
145
+ type: "number"
146
+ },
147
+ {
148
+ displayName: "Max Retries",
149
+ name: "maxRetries",
150
+ default: 2,
151
+ description: "Maximum number of retries to attempt",
152
+ type: "number"
153
+ }
154
+ ]
155
+ }
156
+ ]
157
+ };
158
+ }
159
+ async supplyData(itemIndex) {
160
+ const credentials = await this.getCredentials("cohereApi");
161
+ const modelName = this.getNodeParameter("model", itemIndex);
162
+ const options = this.getNodeParameter("options", itemIndex, {});
163
+ const model = new import_cohere.ChatCohere({
164
+ apiKey: credentials.apiKey,
165
+ model: modelName,
166
+ temperature: options.temperature,
167
+ maxRetries: options.maxRetries ?? 2,
168
+ callbacks: [new import_N8nLlmTracing.N8nLlmTracing(this, { tokensUsageParser })],
169
+ onFailedAttempt: (0, import_n8nLlmFailedAttemptHandler.makeN8nLlmFailedAttemptHandler)(this)
170
+ });
171
+ return {
172
+ response: model
173
+ };
174
+ }
175
+ }
176
+ // Annotate the CommonJS export names for ESM import in node:
177
+ 0 && (module.exports = {
178
+ LmChatCohere,
179
+ tokensUsageParser
180
+ });
181
+ //# sourceMappingURL=LmChatCohere.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../nodes/llms/LmChatCohere/LmChatCohere.node.ts"],"sourcesContent":["import { ChatCohere } from '@langchain/cohere';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n} from 'n8n-workflow';\n\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport function tokensUsageParser(result: LLMResult): {\n\tcompletionTokens: number;\n\tpromptTokens: number;\n\ttotalTokens: number;\n} {\n\tlet totalInputTokens = 0;\n\tlet totalOutputTokens = 0;\n\n\tresult.generations?.forEach((generationArray) => {\n\t\tgenerationArray.forEach((gen) => {\n\t\t\tconst inputTokens = gen.generationInfo?.meta?.tokens?.inputTokens ?? 0;\n\t\t\tconst outputTokens = gen.generationInfo?.meta?.tokens?.outputTokens ?? 0;\n\n\t\t\ttotalInputTokens += inputTokens;\n\t\t\ttotalOutputTokens += outputTokens;\n\t\t});\n\t});\n\n\treturn {\n\t\tcompletionTokens: totalOutputTokens,\n\t\tpromptTokens: totalInputTokens,\n\t\ttotalTokens: totalInputTokens + totalOutputTokens,\n\t};\n}\n\nexport class LmChatCohere implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Cohere Chat Model',\n\t\tname: 'lmChatCohere',\n\t\ticon: { light: 'file:cohere.svg', dark: 'file:cohere.dark.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: 'Cohere 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.lmchatcohere/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: ['ai_languageModel'],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'cohereApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\trequestDefaults: {\n\t\t\tbaseURL: '={{$credentials?.url}}',\n\t\t\theaders: {\n\t\t\t\taccept: 'application/json',\n\t\t\t\tauthorization: '=Bearer {{$credentials?.apiKey}}',\n\t\t\t},\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField(['ai_chain', 'ai_agent']),\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.cohere.com/docs/models\">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: '/v1/models?page_size=100&endpoint=chat',\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: 'models',\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.name}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.name}}',\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.description}}',\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\tdefault: 'command-a-03-2025',\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: '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: 2, 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],\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<{ url?: string; apiKey?: string }>('cohereApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tmaxRetries: number;\n\t\t\ttemperature?: number;\n\t\t};\n\n\t\tconst model = new ChatCohere({\n\t\t\tapiKey: credentials.apiKey,\n\t\t\tmodel: modelName,\n\t\t\ttemperature: options.temperature,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tcallbacks: [new N8nLlmTracing(this, { tokensUsageParser })],\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":[]}
@@ -0,0 +1,5 @@
1
+ <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.96 23.84C14.0267 23.84 16.16 23.7867 19.1467 22.56C22.6133 21.12 29.44 18.56 34.4 15.8933C37.8667 14.0267 39.36 11.5733 39.36 8.26667C39.36 3.73333 35.68 0 31.0933 0H11.8933C5.33333 0 0 5.33333 0 11.8933C0 18.4533 5.01333 23.84 12.96 23.84Z" fill="white"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M16.2134 31.9999C16.2134 28.7999 18.1334 25.8666 21.12 24.6399L27.1467 22.1333C33.28 19.6266 40 24.1066 40 30.7199C40 35.8399 35.84 39.9999 30.72 39.9999H24.16C19.7867 39.9999 16.2134 36.4266 16.2134 31.9999Z" fill="white"/>
4
+ <path d="M6.88 25.3867C3.09333 25.3867 0 28.4801 0 32.2667V33.1734C0 36.9067 3.09333 40.0001 6.88 40.0001C10.6667 40.0001 13.76 36.9067 13.76 33.1201V32.2134C13.7067 28.4801 10.6667 25.3867 6.88 25.3867Z" fill="white"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.96 23.84C14.0267 23.84 16.16 23.7867 19.1467 22.56C22.6133 21.12 29.44 18.56 34.4 15.8933C37.8667 14.0267 39.36 11.5733 39.36 8.26667C39.36 3.73333 35.68 0 31.0933 0H11.8933C5.33333 0 0 5.33333 0 11.8933C0 18.4533 5.01333 23.84 12.96 23.84Z" fill="#39594D"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M16.2134 31.9999C16.2134 28.7999 18.1334 25.8666 21.12 24.6399L27.1467 22.1333C33.28 19.6266 40 24.1066 40 30.7199C40 35.8399 35.84 39.9999 30.72 39.9999H24.16C19.7867 39.9999 16.2134 36.4266 16.2134 31.9999Z" fill="#D18EE2"/>
4
+ <path d="M6.88 25.3867C3.09333 25.3867 0 28.4801 0 32.2667V33.1734C0 36.9067 3.09333 40.0001 6.88 40.0001C10.6667 40.0001 13.76 36.9067 13.76 33.1201V32.2134C13.7067 28.4801 10.6667 25.3867 6.88 25.3867Z" fill="#FF7759"/>
5
+ </svg>
@@ -67,9 +67,9 @@ class N8nLlmTracing extends import_base.BaseCallbackHandler {
67
67
  this.runsMap = {};
68
68
  this.options = {
69
69
  // Default(OpenAI format) parser
70
- tokensUsageParser: (llmOutput) => {
71
- const completionTokens = llmOutput?.tokenUsage?.completionTokens ?? 0;
72
- const promptTokens = llmOutput?.tokenUsage?.promptTokens ?? 0;
70
+ tokensUsageParser: (result) => {
71
+ const completionTokens = result?.llmOutput?.tokenUsage?.completionTokens ?? 0;
72
+ const promptTokens = result?.llmOutput?.tokenUsage?.promptTokens ?? 0;
73
73
  return {
74
74
  completionTokens,
75
75
  promptTokens,
@@ -98,7 +98,7 @@ class N8nLlmTracing extends import_base.BaseCallbackHandler {
98
98
  promptTokens: 0,
99
99
  totalTokens: 0
100
100
  };
101
- const tokenUsage = this.options.tokensUsageParser(output.llmOutput);
101
+ const tokenUsage = this.options.tokensUsageParser(output);
102
102
  if (output.generations.length > 0) {
103
103
  tokenUsageEstimate.completionTokens = await this.estimateTokensFromGeneration(
104
104
  output.generations
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/llms/N8nLlmTracing.ts"],"sourcesContent":["import { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport { getModelNameForTiktoken } from '@langchain/core/language_models/base';\nimport type {\n\tSerialized,\n\tSerializedNotImplemented,\n\tSerializedSecret,\n} from '@langchain/core/load/serializable';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport pick from 'lodash/pick';\nimport type { IDataObject, ISupplyDataFunctions, JsonObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, NodeError, NodeOperationError } from 'n8n-workflow';\n\nimport { logAiEvent } from '@utils/helpers';\nimport { estimateTokensFromStringList } from '@utils/tokenizer/token-estimator';\n\ntype TokensUsageParser = (llmOutput: LLMResult['llmOutput']) => {\n\tcompletionTokens: number;\n\tpromptTokens: number;\n\ttotalTokens: number;\n};\n\ntype RunDetail = {\n\tindex: number;\n\tmessages: BaseMessage[] | string[] | string;\n\toptions: SerializedSecret | SerializedNotImplemented | SerializedFields;\n};\n\nconst TIKTOKEN_ESTIMATE_MODEL = 'gpt-4o';\nexport class N8nLlmTracing extends BaseCallbackHandler {\n\tname = 'N8nLlmTracing';\n\n\t// This flag makes sure that LangChain will wait for the handlers to finish before continuing\n\t// This is crucial for the handleLLMError handler to work correctly (it should be called before the error is propagated to the root node)\n\tawaitHandlers = true;\n\n\tconnectionType = NodeConnectionTypes.AiLanguageModel;\n\n\tpromptTokensEstimate = 0;\n\n\tcompletionTokensEstimate = 0;\n\n\t#parentRunIndex?: number;\n\n\t/**\n\t * A map to associate LLM run IDs to run details.\n\t * Key: Unique identifier for each LLM run (run ID)\n\t * Value: RunDetails object\n\t *\n\t */\n\trunsMap: Record<string, RunDetail> = {};\n\n\toptions = {\n\t\t// Default(OpenAI format) parser\n\t\ttokensUsageParser: (llmOutput: LLMResult['llmOutput']) => {\n\t\t\tconst completionTokens = (llmOutput?.tokenUsage?.completionTokens as number) ?? 0;\n\t\t\tconst promptTokens = (llmOutput?.tokenUsage?.promptTokens as number) ?? 0;\n\n\t\t\treturn {\n\t\t\t\tcompletionTokens,\n\t\t\t\tpromptTokens,\n\t\t\t\ttotalTokens: completionTokens + promptTokens,\n\t\t\t};\n\t\t},\n\t\terrorDescriptionMapper: (error: NodeError) => error.description,\n\t};\n\n\tconstructor(\n\t\tprivate executionFunctions: ISupplyDataFunctions,\n\t\toptions?: {\n\t\t\ttokensUsageParser?: TokensUsageParser;\n\t\t\terrorDescriptionMapper?: (error: NodeError) => string;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.options = { ...this.options, ...options };\n\t}\n\n\tasync estimateTokensFromGeneration(generations: LLMResult['generations']) {\n\t\tconst messages = generations.flatMap((gen) => gen.map((g) => g.text));\n\t\treturn await this.estimateTokensFromStringList(messages);\n\t}\n\n\tasync estimateTokensFromStringList(list: string[]) {\n\t\tconst embeddingModel = getModelNameForTiktoken(TIKTOKEN_ESTIMATE_MODEL);\n\t\treturn await estimateTokensFromStringList(list, embeddingModel);\n\t}\n\n\tasync handleLLMEnd(output: LLMResult, runId: string) {\n\t\t// The fallback should never happen since handleLLMStart should always set the run details\n\t\t// but just in case, we set the index to the length of the runsMap\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\toutput.generations = output.generations.map((gen) =>\n\t\t\tgen.map((g) => pick(g, ['text', 'generationInfo'])),\n\t\t);\n\n\t\tconst tokenUsageEstimate = {\n\t\t\tcompletionTokens: 0,\n\t\t\tpromptTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t};\n\t\tconst tokenUsage = this.options.tokensUsageParser(output.llmOutput);\n\n\t\tif (output.generations.length > 0) {\n\t\t\ttokenUsageEstimate.completionTokens = await this.estimateTokensFromGeneration(\n\t\t\t\toutput.generations,\n\t\t\t);\n\n\t\t\ttokenUsageEstimate.promptTokens = this.promptTokensEstimate;\n\t\t\ttokenUsageEstimate.totalTokens =\n\t\t\t\ttokenUsageEstimate.completionTokens + this.promptTokensEstimate;\n\t\t}\n\t\tconst response: {\n\t\t\tresponse: { generations: LLMResult['generations'] };\n\t\t\ttokenUsageEstimate?: typeof tokenUsageEstimate;\n\t\t\ttokenUsage?: typeof tokenUsage;\n\t\t} = {\n\t\t\tresponse: { generations: output.generations },\n\t\t};\n\n\t\t// If the LLM response contains actual tokens usage, otherwise fallback to the estimate\n\t\tif (tokenUsage.completionTokens > 0) {\n\t\t\tresponse.tokenUsage = tokenUsage;\n\t\t} else {\n\t\t\tresponse.tokenUsageEstimate = tokenUsageEstimate;\n\t\t}\n\n\t\tconst parsedMessages =\n\t\t\ttypeof runDetails.messages === 'string'\n\t\t\t\t? runDetails.messages\n\t\t\t\t: runDetails.messages.map((message) => {\n\t\t\t\t\t\tif (typeof message === 'string') return message;\n\t\t\t\t\t\tif (typeof message?.toJSON === 'function') return message.toJSON();\n\n\t\t\t\t\t\treturn message;\n\t\t\t\t\t});\n\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined ? this.#parentRunIndex + runDetails.index : undefined;\n\n\t\tthis.executionFunctions.addOutputData(\n\t\t\tthis.connectionType,\n\t\t\trunDetails.index,\n\t\t\t[[{ json: { ...response } }]],\n\t\t\tundefined,\n\t\t\tsourceNodeRunIndex,\n\t\t);\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-generated-output', {\n\t\t\tmessages: parsedMessages,\n\t\t\toptions: runDetails.options,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync handleLLMStart(llm: Serialized, prompts: string[], runId: string) {\n\t\tconst estimatedTokens = await this.estimateTokensFromStringList(prompts);\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined\n\t\t\t\t? this.#parentRunIndex + this.executionFunctions.getNextRunIndex()\n\t\t\t\t: undefined;\n\n\t\tconst options = llm.type === 'constructor' ? llm.kwargs : llm;\n\t\tconst { index } = this.executionFunctions.addInputData(\n\t\t\tthis.connectionType,\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tmessages: prompts,\n\t\t\t\t\t\t\testimatedTokens,\n\t\t\t\t\t\t\toptions,\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\tsourceNodeRunIndex,\n\t\t);\n\n\t\t// Save the run details for later use when processing `handleLLMEnd` event\n\t\tthis.runsMap[runId] = {\n\t\t\tindex,\n\t\t\toptions,\n\t\t\tmessages: prompts,\n\t\t};\n\t\tthis.promptTokensEstimate = estimatedTokens;\n\t}\n\n\tasync handleLLMError(error: IDataObject | Error, runId: string, parentRunId?: string) {\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\t// Filter out non-x- headers to avoid leaking sensitive information in logs\n\t\tif (typeof error === 'object' && error?.hasOwnProperty('headers')) {\n\t\t\tconst errorWithHeaders = error as { headers: Record<string, unknown> };\n\n\t\t\tObject.keys(errorWithHeaders.headers).forEach((key) => {\n\t\t\t\tif (!key.startsWith('x-')) {\n\t\t\t\t\tdelete errorWithHeaders.headers[key];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (error instanceof NodeError) {\n\t\t\tif (this.options.errorDescriptionMapper) {\n\t\t\t\terror.description = this.options.errorDescriptionMapper(error);\n\t\t\t}\n\n\t\t\tthis.executionFunctions.addOutputData(this.connectionType, runDetails.index, error);\n\t\t} else {\n\t\t\t// If the error is not a NodeError, we wrap it in a NodeOperationError\n\t\t\tthis.executionFunctions.addOutputData(\n\t\t\t\tthis.connectionType,\n\t\t\t\trunDetails.index,\n\t\t\t\tnew NodeOperationError(this.executionFunctions.getNode(), error as JsonObject, {\n\t\t\t\t\tfunctionality: 'configuration-node',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-errored', {\n\t\t\terror: Object.keys(error).length === 0 ? error.toString() : error,\n\t\t\trunId,\n\t\t\tparentRunId,\n\t\t});\n\t}\n\n\t// Used to associate subsequent runs with the correct parent run in subnodes of subnodes\n\tsetParentRunIndex(runIndex: number) {\n\t\tthis.#parentRunIndex = runIndex;\n\t}\n}\n"],"mappings":"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","names":["import_base","pick"]}
1
+ {"version":3,"sources":["../../../nodes/llms/N8nLlmTracing.ts"],"sourcesContent":["import { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport { getModelNameForTiktoken } from '@langchain/core/language_models/base';\nimport type {\n\tSerialized,\n\tSerializedNotImplemented,\n\tSerializedSecret,\n} from '@langchain/core/load/serializable';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport pick from 'lodash/pick';\nimport type { IDataObject, ISupplyDataFunctions, JsonObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, NodeError, NodeOperationError } from 'n8n-workflow';\n\nimport { logAiEvent } from '@utils/helpers';\nimport { estimateTokensFromStringList } from '@utils/tokenizer/token-estimator';\n\ntype TokensUsageParser = (result: LLMResult) => {\n\tcompletionTokens: number;\n\tpromptTokens: number;\n\ttotalTokens: number;\n};\n\ntype RunDetail = {\n\tindex: number;\n\tmessages: BaseMessage[] | string[] | string;\n\toptions: SerializedSecret | SerializedNotImplemented | SerializedFields;\n};\n\nconst TIKTOKEN_ESTIMATE_MODEL = 'gpt-4o';\nexport class N8nLlmTracing extends BaseCallbackHandler {\n\tname = 'N8nLlmTracing';\n\n\t// This flag makes sure that LangChain will wait for the handlers to finish before continuing\n\t// This is crucial for the handleLLMError handler to work correctly (it should be called before the error is propagated to the root node)\n\tawaitHandlers = true;\n\n\tconnectionType = NodeConnectionTypes.AiLanguageModel;\n\n\tpromptTokensEstimate = 0;\n\n\tcompletionTokensEstimate = 0;\n\n\t#parentRunIndex?: number;\n\n\t/**\n\t * A map to associate LLM run IDs to run details.\n\t * Key: Unique identifier for each LLM run (run ID)\n\t * Value: RunDetails object\n\t *\n\t */\n\trunsMap: Record<string, RunDetail> = {};\n\n\toptions = {\n\t\t// Default(OpenAI format) parser\n\t\ttokensUsageParser: (result: LLMResult) => {\n\t\t\tconst completionTokens = (result?.llmOutput?.tokenUsage?.completionTokens as number) ?? 0;\n\t\t\tconst promptTokens = (result?.llmOutput?.tokenUsage?.promptTokens as number) ?? 0;\n\n\t\t\treturn {\n\t\t\t\tcompletionTokens,\n\t\t\t\tpromptTokens,\n\t\t\t\ttotalTokens: completionTokens + promptTokens,\n\t\t\t};\n\t\t},\n\t\terrorDescriptionMapper: (error: NodeError) => error.description,\n\t};\n\n\tconstructor(\n\t\tprivate executionFunctions: ISupplyDataFunctions,\n\t\toptions?: {\n\t\t\ttokensUsageParser?: TokensUsageParser;\n\t\t\terrorDescriptionMapper?: (error: NodeError) => string;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.options = { ...this.options, ...options };\n\t}\n\n\tasync estimateTokensFromGeneration(generations: LLMResult['generations']) {\n\t\tconst messages = generations.flatMap((gen) => gen.map((g) => g.text));\n\t\treturn await this.estimateTokensFromStringList(messages);\n\t}\n\n\tasync estimateTokensFromStringList(list: string[]) {\n\t\tconst embeddingModel = getModelNameForTiktoken(TIKTOKEN_ESTIMATE_MODEL);\n\t\treturn await estimateTokensFromStringList(list, embeddingModel);\n\t}\n\n\tasync handleLLMEnd(output: LLMResult, runId: string) {\n\t\t// The fallback should never happen since handleLLMStart should always set the run details\n\t\t// but just in case, we set the index to the length of the runsMap\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\toutput.generations = output.generations.map((gen) =>\n\t\t\tgen.map((g) => pick(g, ['text', 'generationInfo'])),\n\t\t);\n\n\t\tconst tokenUsageEstimate = {\n\t\t\tcompletionTokens: 0,\n\t\t\tpromptTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t};\n\t\tconst tokenUsage = this.options.tokensUsageParser(output);\n\n\t\tif (output.generations.length > 0) {\n\t\t\ttokenUsageEstimate.completionTokens = await this.estimateTokensFromGeneration(\n\t\t\t\toutput.generations,\n\t\t\t);\n\n\t\t\ttokenUsageEstimate.promptTokens = this.promptTokensEstimate;\n\t\t\ttokenUsageEstimate.totalTokens =\n\t\t\t\ttokenUsageEstimate.completionTokens + this.promptTokensEstimate;\n\t\t}\n\t\tconst response: {\n\t\t\tresponse: { generations: LLMResult['generations'] };\n\t\t\ttokenUsageEstimate?: typeof tokenUsageEstimate;\n\t\t\ttokenUsage?: typeof tokenUsage;\n\t\t} = {\n\t\t\tresponse: { generations: output.generations },\n\t\t};\n\n\t\t// If the LLM response contains actual tokens usage, otherwise fallback to the estimate\n\t\tif (tokenUsage.completionTokens > 0) {\n\t\t\tresponse.tokenUsage = tokenUsage;\n\t\t} else {\n\t\t\tresponse.tokenUsageEstimate = tokenUsageEstimate;\n\t\t}\n\n\t\tconst parsedMessages =\n\t\t\ttypeof runDetails.messages === 'string'\n\t\t\t\t? runDetails.messages\n\t\t\t\t: runDetails.messages.map((message) => {\n\t\t\t\t\t\tif (typeof message === 'string') return message;\n\t\t\t\t\t\tif (typeof message?.toJSON === 'function') return message.toJSON();\n\n\t\t\t\t\t\treturn message;\n\t\t\t\t\t});\n\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined ? this.#parentRunIndex + runDetails.index : undefined;\n\n\t\tthis.executionFunctions.addOutputData(\n\t\t\tthis.connectionType,\n\t\t\trunDetails.index,\n\t\t\t[[{ json: { ...response } }]],\n\t\t\tundefined,\n\t\t\tsourceNodeRunIndex,\n\t\t);\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-generated-output', {\n\t\t\tmessages: parsedMessages,\n\t\t\toptions: runDetails.options,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync handleLLMStart(llm: Serialized, prompts: string[], runId: string) {\n\t\tconst estimatedTokens = await this.estimateTokensFromStringList(prompts);\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined\n\t\t\t\t? this.#parentRunIndex + this.executionFunctions.getNextRunIndex()\n\t\t\t\t: undefined;\n\n\t\tconst options = llm.type === 'constructor' ? llm.kwargs : llm;\n\t\tconst { index } = this.executionFunctions.addInputData(\n\t\t\tthis.connectionType,\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tmessages: prompts,\n\t\t\t\t\t\t\testimatedTokens,\n\t\t\t\t\t\t\toptions,\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\tsourceNodeRunIndex,\n\t\t);\n\n\t\t// Save the run details for later use when processing `handleLLMEnd` event\n\t\tthis.runsMap[runId] = {\n\t\t\tindex,\n\t\t\toptions,\n\t\t\tmessages: prompts,\n\t\t};\n\t\tthis.promptTokensEstimate = estimatedTokens;\n\t}\n\n\tasync handleLLMError(error: IDataObject | Error, runId: string, parentRunId?: string) {\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\t// Filter out non-x- headers to avoid leaking sensitive information in logs\n\t\tif (typeof error === 'object' && error?.hasOwnProperty('headers')) {\n\t\t\tconst errorWithHeaders = error as { headers: Record<string, unknown> };\n\n\t\t\tObject.keys(errorWithHeaders.headers).forEach((key) => {\n\t\t\t\tif (!key.startsWith('x-')) {\n\t\t\t\t\tdelete errorWithHeaders.headers[key];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (error instanceof NodeError) {\n\t\t\tif (this.options.errorDescriptionMapper) {\n\t\t\t\terror.description = this.options.errorDescriptionMapper(error);\n\t\t\t}\n\n\t\t\tthis.executionFunctions.addOutputData(this.connectionType, runDetails.index, error);\n\t\t} else {\n\t\t\t// If the error is not a NodeError, we wrap it in a NodeOperationError\n\t\t\tthis.executionFunctions.addOutputData(\n\t\t\t\tthis.connectionType,\n\t\t\t\trunDetails.index,\n\t\t\t\tnew NodeOperationError(this.executionFunctions.getNode(), error as JsonObject, {\n\t\t\t\t\tfunctionality: 'configuration-node',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-errored', {\n\t\t\terror: Object.keys(error).length === 0 ? error.toString() : error,\n\t\t\trunId,\n\t\t\tparentRunId,\n\t\t});\n\t}\n\n\t// Used to associate subsequent runs with the correct parent run in subnodes of subnodes\n\tsetParentRunIndex(runIndex: number) {\n\t\tthis.#parentRunIndex = runIndex;\n\t}\n}\n"],"mappings":"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","names":["import_base","pick"]}
@@ -36,7 +36,7 @@ class McpClientTool {
36
36
  dark: "file:../mcp.dark.svg"
37
37
  },
38
38
  group: ["output"],
39
- version: 1,
39
+ version: [1, 1.1],
40
40
  description: "Connect tools from an MCP Server",
41
41
  defaults: {
42
42
  name: "MCP Client"
@@ -87,7 +87,48 @@ class McpClientTool {
87
87
  description: "SSE Endpoint of your MCP server",
88
88
  placeholder: "e.g. https://my-mcp-server.ai/sse",
89
89
  default: "",
90
- required: true
90
+ required: true,
91
+ displayOptions: {
92
+ show: {
93
+ "@version": [1]
94
+ }
95
+ }
96
+ },
97
+ {
98
+ displayName: "Endpoint",
99
+ name: "endpointUrl",
100
+ type: "string",
101
+ description: "Endpoint of your MCP server",
102
+ placeholder: "e.g. https://my-mcp-server.ai/mcp",
103
+ default: "",
104
+ required: true,
105
+ displayOptions: {
106
+ show: {
107
+ "@version": [{ _cnd: { gte: 1.1 } }]
108
+ }
109
+ }
110
+ },
111
+ {
112
+ displayName: "Server Transport",
113
+ name: "serverTransport",
114
+ type: "options",
115
+ options: [
116
+ {
117
+ name: "Server Sent Events (Deprecated)",
118
+ value: "sse"
119
+ },
120
+ {
121
+ name: "HTTP Streamable",
122
+ value: "httpStreamable"
123
+ }
124
+ ],
125
+ default: "sse",
126
+ description: "The transport used by your endpoint",
127
+ displayOptions: {
128
+ show: {
129
+ "@version": [{ _cnd: { gte: 1.1 } }]
130
+ }
131
+ }
91
132
  },
92
133
  {
93
134
  displayName: "Authentication",
@@ -108,7 +149,7 @@ class McpClientTool {
108
149
  }
109
150
  ],
110
151
  default: "none",
111
- description: "The way to authenticate with your SSE endpoint"
152
+ description: "The way to authenticate with your endpoint"
112
153
  },
113
154
  {
114
155
  displayName: "Credentials",
@@ -189,11 +230,20 @@ class McpClientTool {
189
230
  "authentication",
190
231
  itemIndex
191
232
  );
192
- const sseEndpoint = this.getNodeParameter("sseEndpoint", itemIndex);
193
233
  const node = this.getNode();
234
+ let serverTransport;
235
+ let endpointUrl;
236
+ if (node.typeVersion === 1) {
237
+ serverTransport = "sse";
238
+ endpointUrl = this.getNodeParameter("sseEndpoint", itemIndex);
239
+ } else {
240
+ serverTransport = this.getNodeParameter("serverTransport", itemIndex);
241
+ endpointUrl = this.getNodeParameter("endpointUrl", itemIndex);
242
+ }
194
243
  const { headers } = await (0, import_utils.getAuthHeaders)(this, authentication);
195
244
  const client = await (0, import_utils.connectMcpClient)({
196
- sseEndpoint,
245
+ serverTransport,
246
+ endpointUrl,
197
247
  headers,
198
248
  name: node.type,
199
249
  version: node.typeVersion
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import {\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { getTools } from './loadOptions';\nimport type { 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,\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},\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 SSE 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],\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 sseEndpoint = this.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t\tconst node = this.getNode();\n\t\tconst { headers } = await getAuthHeaders(this, authentication);\n\t\tconst client = await connectMcpClient({\n\t\t\tsseEndpoint,\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, (error) => {\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t\tthrow new NodeOperationError(node, `Failed to execute tool \"${tool.name}\"`, {\n\t\t\t\t\t\t\tdescription: error,\n\t\t\t\t\t\t});\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\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '@utils/logWrapper';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { getTools } from './loadOptions';\nimport type { McpServerTransport, McpAuthenticationOption, McpToolIncludeMode } from './types';\nimport {\n\tconnectMcpClient,\n\tcreateCallTool,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tgetSelectedTools,\n\tMcpToolkit,\n\tmcpToolToDynamicTool,\n} from './utils';\n\nexport class McpClientTool implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Client Tool',\n\t\tname: 'mcpClientTool',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Connect tools from an MCP Server',\n\t\tdefaults: {\n\t\t\tname: 'MCP Client',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Model Context Protocol', 'Tools'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Client'],\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' }],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBearerAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'httpHeaderAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'SSE Endpoint',\n\t\t\t\tname: 'sseEndpoint',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'SSE Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/sse',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Endpoint',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Server Transport',\n\t\t\t\tname: 'serverTransport',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Server Sent Events (Deprecated)',\n\t\t\t\t\t\tvalue: 'sse',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'HTTP Streamable',\n\t\t\t\t\t\tvalue: 'httpStreamable',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'sse',\n\t\t\t\tdescription: 'The transport used by your endpoint',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'include',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription: 'How to select the tools you want to be exposed to the AI Agent',\n\t\t\t\tdefault: 'all',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All',\n\t\t\t\t\t\tvalue: 'all',\n\t\t\t\t\t\tdescription: 'Also include all unchanged fields from the input',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Selected',\n\t\t\t\t\t\tvalue: 'selected',\n\t\t\t\t\t\tdescription: 'Also include the tools listed in the parameter \"Tools to Include\"',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All Except',\n\t\t\t\t\t\tvalue: 'except',\n\t\t\t\t\t\tdescription: 'Exclude the tools listed in the parameter \"Tools to Exclude\"',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'includeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t\tloadOptionsDependsOn: ['sseEndpoint'],\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['selected'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Exclude',\n\t\t\t\tname: 'excludeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['except'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\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\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, (error) => {\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t\tthrow new NodeOperationError(node, `Failed to execute tool \"${tool.name}\"`, {\n\t\t\t\t\t\t\tdescription: error,\n\t\t\t\t\t\t});\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":[]}
@@ -25,11 +25,20 @@ var import_n8n_workflow = require("n8n-workflow");
25
25
  var import_utils = require("./utils");
26
26
  async function getTools() {
27
27
  const authentication = this.getNodeParameter("authentication");
28
- const sseEndpoint = this.getNodeParameter("sseEndpoint");
29
28
  const node = this.getNode();
29
+ let serverTransport;
30
+ let endpointUrl;
31
+ if (node.typeVersion === 1) {
32
+ serverTransport = "sse";
33
+ endpointUrl = this.getNodeParameter("sseEndpoint");
34
+ } else {
35
+ serverTransport = this.getNodeParameter("serverTransport");
36
+ endpointUrl = this.getNodeParameter("endpointUrl");
37
+ }
30
38
  const { headers } = await (0, import_utils.getAuthHeaders)(this, authentication);
31
39
  const client = await (0, import_utils.connectMcpClient)({
32
- sseEndpoint,
40
+ serverTransport,
41
+ endpointUrl,
33
42
  headers,
34
43
  name: node.type,
35
44
  version: node.typeVersion
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/loadOptions.ts"],"sourcesContent":["import {\n\ttype ILoadOptionsFunctions,\n\ttype INodePropertyOptions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport type { McpAuthenticationOption } from './types';\nimport { connectMcpClient, getAllTools, getAuthHeaders } from './utils';\n\nexport async function getTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst sseEndpoint = this.getNodeParameter('sseEndpoint') as string;\n\tconst node = this.getNode();\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tsseEndpoint,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t});\n\n\tif (!client.ok) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Could not connect to your MCP server');\n\t}\n\n\tconst tools = await getAllTools(client.result);\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tvalue: tool.name,\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t}));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAIO;AAGP,mBAA8D;AAE9D,eAAsB,WAAuE;AAC5F,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,cAAc,KAAK,iBAAiB,aAAa;AACvD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,EACf,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,UAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,sCAAsC;AAAA,EACpF;AAEA,QAAM,QAAQ,UAAM,0BAAY,OAAO,MAAM;AAC7C,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC3B,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACnB,EAAE;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/loadOptions.ts"],"sourcesContent":["import {\n\ttype ILoadOptionsFunctions,\n\ttype INodePropertyOptions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport type { McpAuthenticationOption, McpServerTransport } from './types';\nimport { connectMcpClient, getAllTools, getAuthHeaders } from './utils';\n\nexport async function getTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst node = this.getNode();\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = this.getNodeParameter('sseEndpoint') as string;\n\t} else {\n\t\tserverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\t\tendpointUrl = this.getNodeParameter('endpointUrl') as string;\n\t}\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t});\n\n\tif (!client.ok) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Could not connect to your MCP server');\n\t}\n\n\tconst tools = await getAllTools(client.result);\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tvalue: tool.name,\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t}));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAIO;AAGP,mBAA8D;AAE9D,eAAsB,WAAuE;AAC5F,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI;AACJ,MAAI;AACJ,MAAI,KAAK,gBAAgB,GAAG;AAC3B,sBAAkB;AAClB,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD,OAAO;AACN,sBAAkB,KAAK,iBAAiB,iBAAiB;AACzD,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD;AACA,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,EACf,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,UAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,sCAAsC;AAAA,EACpF;AAEA,QAAM,QAAQ,UAAM,0BAAY,OAAO,MAAM;AAC7C,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC3B,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACnB,EAAE;AACH;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/types.ts"],"sourcesContent":["import type { JSONSchema7 } from 'json-schema';\n\nexport type McpTool = { name: string; description?: string; inputSchema: JSONSchema7 };\n\nexport type McpToolIncludeMode = 'all' | 'selected' | 'except';\n\nexport type McpAuthenticationOption = 'none' | 'headerAuth' | 'bearerAuth';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/mcp/McpClientTool/types.ts"],"sourcesContent":["import type { JSONSchema7 } from 'json-schema';\n\nexport type McpTool = { name: string; description?: string; inputSchema: JSONSchema7 };\n\nexport type McpServerTransport = 'sse' | 'httpStreamable';\n\nexport type McpToolIncludeMode = 'all' | 'selected' | 'except';\n\nexport type McpAuthenticationOption = 'none' | 'headerAuth' | 'bearerAuth';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -31,6 +31,7 @@ module.exports = __toCommonJS(utils_exports);
31
31
  var import_tools = require("@langchain/core/tools");
32
32
  var import_client = require("@modelcontextprotocol/sdk/client/index.js");
33
33
  var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
34
+ var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
34
35
  var import_types = require("@modelcontextprotocol/sdk/types.js");
35
36
  var import_agents = require("langchain/agents");
36
37
  var import_n8n_workflow = require("n8n-workflow");
@@ -132,16 +133,29 @@ function normalizeAndValidateUrl(input) {
132
133
  }
133
134
  async function connectMcpClient({
134
135
  headers,
135
- sseEndpoint,
136
+ serverTransport,
137
+ endpointUrl,
136
138
  name,
137
139
  version
138
140
  }) {
139
- try {
140
- const endpoint = normalizeAndValidateUrl(sseEndpoint);
141
- if (!endpoint.ok) {
142
- return (0, import_n8n_workflow.createResultError)({ type: "invalid_url", error: endpoint.error });
141
+ const endpoint = normalizeAndValidateUrl(endpointUrl);
142
+ if (!endpoint.ok) {
143
+ return (0, import_n8n_workflow.createResultError)({ type: "invalid_url", error: endpoint.error });
144
+ }
145
+ const client = new import_client.Client({ name, version: version.toString() }, { capabilities: { tools: {} } });
146
+ if (serverTransport === "httpStreamable") {
147
+ try {
148
+ const transport = new import_streamableHttp.StreamableHTTPClientTransport(endpoint.result, {
149
+ requestInit: { headers }
150
+ });
151
+ await client.connect(transport);
152
+ return (0, import_n8n_workflow.createResultOk)(client);
153
+ } catch (error) {
154
+ return (0, import_n8n_workflow.createResultError)({ type: "connection", error });
143
155
  }
144
- const transport = new import_sse.SSEClientTransport(endpoint.result, {
156
+ }
157
+ try {
158
+ const sseTransport = new import_sse.SSEClientTransport(endpoint.result, {
145
159
  eventSourceInit: {
146
160
  fetch: async (url, init) => await fetch(url, {
147
161
  ...init,
@@ -153,11 +167,7 @@ async function connectMcpClient({
153
167
  },
154
168
  requestInit: { headers }
155
169
  });
156
- const client = new import_client.Client(
157
- { name, version: version.toString() },
158
- { capabilities: { tools: {} } }
159
- );
160
- await client.connect(transport);
170
+ await client.connect(sseTransport);
161
171
  return (0, import_n8n_workflow.createResultOk)(client);
162
172
  } catch (error) {
163
173
  return (0, import_n8n_workflow.createResultError)({ type: "connection", error });