@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.
- package/dist/credentials/CohereApi.credentials.js +7 -1
- package/dist/credentials/CohereApi.credentials.js.map +1 -1
- package/dist/known/credentials.json +3 -0
- package/dist/known/nodes.json +16 -0
- package/dist/nodes/agents/Agent/Agent.node.js +1 -0
- package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
- package/dist/nodes/agents/Agent/AgentTool.node.js +57 -0
- package/dist/nodes/agents/Agent/AgentTool.node.js.map +1 -0
- package/dist/nodes/agents/Agent/V2/AgentToolV2.node.js +104 -0
- package/dist/nodes/agents/Agent/V2/AgentToolV2.node.js.map +1 -0
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js +4 -66
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -1
- package/dist/nodes/agents/Agent/V2/utils.js +92 -0
- package/dist/nodes/agents/Agent/V2/utils.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js +13 -10
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +14 -7
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -1
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +1 -1
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
- package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js +13 -2
- package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +2 -2
- package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
- package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js +2 -0
- package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js.map +1 -1
- package/dist/nodes/llms/LmChatCohere/LmChatCohere.node.js +181 -0
- package/dist/nodes/llms/LmChatCohere/LmChatCohere.node.js.map +1 -0
- package/dist/nodes/llms/LmChatCohere/cohere.dark.svg +5 -0
- package/dist/nodes/llms/LmChatCohere/cohere.svg +5 -0
- package/dist/nodes/llms/N8nLlmTracing.js +4 -4
- package/dist/nodes/llms/N8nLlmTracing.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +55 -5
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/loadOptions.js +11 -2
- package/dist/nodes/mcp/McpClientTool/loadOptions.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/types.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/utils.js +21 -11
- package/dist/nodes/mcp/McpClientTool/utils.js.map +1 -1
- package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js +1 -1
- package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js.map +1 -1
- package/dist/nodes/tools/ToolCode/ToolCode.node.js +1 -2
- package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
- package/dist/nodes/tools/ToolThink/ToolThink.node.js +5 -2
- package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +1 -2
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +2 -2
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +2 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/templates.js +3 -1
- package/dist/nodes/trigger/ChatTrigger/templates.js.map +1 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js +2 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js.map +1 -1
- package/dist/nodes/vendors/Anthropic/Anthropic.node.js +42 -0
- package/dist/nodes/vendors/Anthropic/Anthropic.node.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/descriptions.js +52 -0
- package/dist/nodes/vendors/Anthropic/actions/descriptions.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/document/analyze.operation.js +125 -0
- package/dist/nodes/vendors/Anthropic/actions/document/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/document/index.js +64 -0
- package/dist/nodes/vendors/Anthropic/actions/document/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/file/delete.operation.js +61 -0
- package/dist/nodes/vendors/Anthropic/actions/file/delete.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/file/get.operation.js +63 -0
- package/dist/nodes/vendors/Anthropic/actions/file/get.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/file/index.js +94 -0
- package/dist/nodes/vendors/Anthropic/actions/file/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/file/list.operation.js +108 -0
- package/dist/nodes/vendors/Anthropic/actions/file/list.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/file/upload.operation.js +126 -0
- package/dist/nodes/vendors/Anthropic/actions/file/upload.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/image/analyze.operation.js +125 -0
- package/dist/nodes/vendors/Anthropic/actions/image/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/image/index.js +64 -0
- package/dist/nodes/vendors/Anthropic/actions/image/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/node.type.js +17 -0
- package/dist/nodes/vendors/Anthropic/actions/node.type.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/generate.operation.js +87 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/generate.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/improve.operation.js +154 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/improve.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/index.js +95 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/templatize.operation.js +146 -0
- package/dist/nodes/vendors/Anthropic/actions/prompt/templatize.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/router.js +93 -0
- package/dist/nodes/vendors/Anthropic/actions/router.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/text/index.js +64 -0
- package/dist/nodes/vendors/Anthropic/actions/text/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/text/message.operation.js +540 -0
- package/dist/nodes/vendors/Anthropic/actions/text/message.operation.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/actions/versionDescription.js +125 -0
- package/dist/nodes/vendors/Anthropic/actions/versionDescription.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/anthropic.svg +1 -0
- package/dist/nodes/vendors/Anthropic/helpers/baseAnalyze.js +109 -0
- package/dist/nodes/vendors/Anthropic/helpers/baseAnalyze.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/helpers/interfaces.js +17 -0
- package/dist/nodes/vendors/Anthropic/helpers/interfaces.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/helpers/utils.js +84 -0
- package/dist/nodes/vendors/Anthropic/helpers/utils.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/methods/index.js +39 -0
- package/dist/nodes/vendors/Anthropic/methods/index.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/methods/listSearch.js +42 -0
- package/dist/nodes/vendors/Anthropic/methods/listSearch.js.map +1 -0
- package/dist/nodes/vendors/Anthropic/transport/index.js +57 -0
- package/dist/nodes/vendors/Anthropic/transport/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/GoogleGemini.node.js +42 -0
- package/dist/nodes/vendors/GoogleGemini/GoogleGemini.node.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/analyze.operation.js +125 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/index.js +74 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/transcribe.operation.js +184 -0
- package/dist/nodes/vendors/GoogleGemini/actions/audio/transcribe.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/descriptions.js +52 -0
- package/dist/nodes/vendors/GoogleGemini/actions/descriptions.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/document/analyze.operation.js +125 -0
- package/dist/nodes/vendors/GoogleGemini/actions/document/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/document/index.js +64 -0
- package/dist/nodes/vendors/GoogleGemini/actions/document/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/file/index.js +64 -0
- package/dist/nodes/vendors/GoogleGemini/actions/file/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/file/upload.operation.js +119 -0
- package/dist/nodes/vendors/GoogleGemini/actions/file/upload.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/analyze.operation.js +125 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js +167 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/index.js +74 -0
- package/dist/nodes/vendors/GoogleGemini/actions/image/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/node.type.js +17 -0
- package/dist/nodes/vendors/GoogleGemini/actions/node.type.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/router.js +97 -0
- package/dist/nodes/vendors/GoogleGemini/actions/router.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/text/index.js +64 -0
- package/dist/nodes/vendors/GoogleGemini/actions/text/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/text/message.operation.js +339 -0
- package/dist/nodes/vendors/GoogleGemini/actions/text/message.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/versionDescription.js +131 -0
- package/dist/nodes/vendors/GoogleGemini/actions/versionDescription.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/analyze.operation.js +125 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/analyze.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/download.operation.js +88 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/download.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/generate.operation.js +228 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/generate.operation.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/index.js +84 -0
- package/dist/nodes/vendors/GoogleGemini/actions/video/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/gemini.svg +1 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/baseAnalyze.js +100 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/baseAnalyze.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/interfaces.js +17 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/interfaces.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/utils.js +91 -0
- package/dist/nodes/vendors/GoogleGemini/helpers/utils.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/methods/index.js +39 -0
- package/dist/nodes/vendors/GoogleGemini/methods/index.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js +74 -0
- package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js.map +1 -0
- package/dist/nodes/vendors/GoogleGemini/transport/index.js +48 -0
- package/dist/nodes/vendors/GoogleGemini/transport/index.js.map +1 -0
- package/dist/nodes/vendors/OpenAi/actions/router.js +1 -1
- package/dist/nodes/vendors/OpenAi/actions/router.js.map +1 -1
- package/dist/types/credentials.json +3 -3
- package/dist/types/nodes.json +9 -5
- package/dist/utils/descriptions.js +13 -2
- package/dist/utils/descriptions.js.map +1 -1
- package/dist/utils/helpers.js +2 -7
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/output_parsers/N8nOutputParser.js.map +1 -1
- 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":"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","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: (
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
136
|
+
serverTransport,
|
|
137
|
+
endpointUrl,
|
|
136
138
|
name,
|
|
137
139
|
version
|
|
138
140
|
}) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 });
|