@n8n/n8n-nodes-langchain 1.93.0 → 1.95.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 (102) hide show
  1. package/dist/credentials/AzureEntraCognitiveServicesOAuth2Api.credentials.js +4 -21
  2. package/dist/credentials/AzureEntraCognitiveServicesOAuth2Api.credentials.js.map +1 -1
  3. package/dist/nodes/agents/Agent/Agent.node.js +19 -394
  4. package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
  5. package/dist/nodes/agents/Agent/V1/AgentV1.node.js +427 -0
  6. package/dist/nodes/agents/Agent/V1/AgentV1.node.js.map +1 -0
  7. package/dist/nodes/agents/Agent/V2/AgentV2.node.js +162 -0
  8. package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -0
  9. package/dist/nodes/agents/Agent/agents/ToolsAgent/{description.js → V1/description.js} +2 -34
  10. package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/description.js.map +1 -0
  11. package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js +119 -0
  12. package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js.map +1 -0
  13. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js +40 -0
  14. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js.map +1 -0
  15. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +139 -0
  16. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -0
  17. package/dist/nodes/agents/Agent/agents/ToolsAgent/{execute.js → common.js} +7 -97
  18. package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -0
  19. package/dist/nodes/agents/Agent/agents/ToolsAgent/options.js +62 -0
  20. package/dist/nodes/agents/Agent/agents/ToolsAgent/options.js.map +1 -0
  21. package/dist/nodes/chains/ChainLLM/ChainLlm.node.js +69 -51
  22. package/dist/nodes/chains/ChainLLM/ChainLlm.node.js.map +1 -1
  23. package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js +8 -0
  24. package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js.map +1 -1
  25. package/dist/nodes/chains/ChainLLM/methods/config.js +5 -0
  26. package/dist/nodes/chains/ChainLLM/methods/config.js.map +1 -1
  27. package/dist/nodes/chains/ChainLLM/methods/processItem.js +66 -0
  28. package/dist/nodes/chains/ChainLLM/methods/processItem.js.map +1 -0
  29. package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js +71 -95
  30. package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js.map +1 -1
  31. package/dist/nodes/chains/ChainRetrievalQA/constants.js +49 -0
  32. package/dist/nodes/chains/ChainRetrievalQA/constants.js.map +1 -0
  33. package/dist/nodes/chains/ChainRetrievalQA/processItem.js +91 -0
  34. package/dist/nodes/chains/ChainRetrievalQA/processItem.js.map +1 -0
  35. package/dist/nodes/chains/ChainSummarization/ChainSummarization.node.js +3 -2
  36. package/dist/nodes/chains/ChainSummarization/ChainSummarization.node.js.map +1 -1
  37. package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js +55 -78
  38. package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js.map +1 -1
  39. package/dist/nodes/chains/ChainSummarization/V2/processItem.js +95 -0
  40. package/dist/nodes/chains/ChainSummarization/V2/processItem.js.map +1 -0
  41. package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js +56 -33
  42. package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js.map +1 -1
  43. package/dist/nodes/chains/InformationExtractor/constants.js +31 -0
  44. package/dist/nodes/chains/InformationExtractor/constants.js.map +1 -0
  45. package/dist/nodes/chains/InformationExtractor/processItem.js +56 -0
  46. package/dist/nodes/chains/InformationExtractor/processItem.js.map +1 -0
  47. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +198 -71
  48. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
  49. package/dist/nodes/chains/TextClassifier/TextClassifier.node.js +83 -54
  50. package/dist/nodes/chains/TextClassifier/TextClassifier.node.js.map +1 -1
  51. package/dist/nodes/chains/TextClassifier/constants.js +29 -0
  52. package/dist/nodes/chains/TextClassifier/constants.js.map +1 -0
  53. package/dist/nodes/chains/TextClassifier/processItem.js +65 -0
  54. package/dist/nodes/chains/TextClassifier/processItem.js.map +1 -0
  55. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +7 -3
  56. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
  57. package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js +4 -1
  58. package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js.map +1 -1
  59. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js +6 -1
  60. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js.map +1 -1
  61. package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js +4 -1
  62. package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js.map +1 -1
  63. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js +4 -0
  64. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js.map +1 -1
  65. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js +4 -0
  66. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js.map +1 -1
  67. package/dist/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.js +16 -2
  68. package/dist/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.js.map +1 -1
  69. package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js +3 -1
  70. package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js.map +1 -1
  71. package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js +2 -0
  72. package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js.map +1 -1
  73. package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js +3 -1
  74. package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js.map +1 -1
  75. package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js +3 -1
  76. package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js.map +1 -1
  77. package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js +2 -2
  78. package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js.map +1 -1
  79. package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +1 -0
  80. package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
  81. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +2 -1
  82. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
  83. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +1 -1
  84. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
  85. package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js +109 -17
  86. package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js.map +1 -1
  87. package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js +3 -0
  88. package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js.map +1 -1
  89. package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js +2 -1
  90. package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js.map +1 -1
  91. package/dist/nodes/vector_store/shared/createVectorStoreNode/types.js.map +1 -1
  92. package/dist/nodes/vendors/OpenAi/actions/image/generate.operation.js +6 -1
  93. package/dist/nodes/vendors/OpenAi/actions/image/generate.operation.js.map +1 -1
  94. package/dist/types/credentials.json +1 -1
  95. package/dist/types/nodes.json +20 -19
  96. package/dist/utils/httpProxyAgent.js +33 -0
  97. package/dist/utils/httpProxyAgent.js.map +1 -0
  98. package/dist/utils/sharedFields.js +29 -0
  99. package/dist/utils/sharedFields.js.map +1 -1
  100. package/package.json +7 -6
  101. package/dist/nodes/agents/Agent/agents/ToolsAgent/description.js.map +0 -1
  102. package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\n\nimport { ChatOpenAI, type ClientOptions } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatOpenRouter implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenRouter Chat Model',\n\t\tname: 'lmChatOpenRouter',\n\t\ticon: { light: 'file:openrouter.svg', dark: 'file:openrouter.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: 'OpenRouter 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.lmchatopenrouter/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openRouterApi',\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: '={{ $credentials?.url }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'If using JSON response format, you must include word \"json\" in the prompt in your chain or agent. Also, make sure to select latest models released post November 2023.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\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://openrouter.ai/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: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'openai/gpt-4o-mini',\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Format',\n\t\t\t\t\t\tname: 'responseFormat',\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Regular text response',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\t\t\tvalue: 'json_object',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\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\t{\n\t\t\t\t\t\tdisplayName: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 360000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\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<OpenAICompatibleCredential>('openRouterApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tmaxRetries: number;\n\t\t\ttimeout: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttopP?: number;\n\t\t\tresponseFormat?: 'text' | 'json_object';\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tbaseURL: credentials.url,\n\t\t};\n\n\t\tconst model = new ChatOpenAI({\n\t\t\topenAIApiKey: credentials.apiKey,\n\t\t\tmodelName,\n\t\t\t...options,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tmodelKwargs: options.responseFormat\n\t\t\t\t? {\n\t\t\t\t\t\tresponse_format: { type: options.responseFormat },\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\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/LmChatOpenRouter/LmChatOpenRouter.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\n\nimport { ChatOpenAI, type ClientOptions } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getHttpProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatOpenRouter implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenRouter Chat Model',\n\t\tname: 'lmChatOpenRouter',\n\t\ticon: { light: 'file:openrouter.svg', dark: 'file:openrouter.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: 'OpenRouter 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.lmchatopenrouter/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openRouterApi',\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: '={{ $credentials?.url }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'If using JSON response format, you must include word \"json\" in the prompt in your chain or agent. Also, make sure to select latest models released post November 2023.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\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://openrouter.ai/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: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'openai/gpt-4o-mini',\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Format',\n\t\t\t\t\t\tname: 'responseFormat',\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Regular text response',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\t\t\tvalue: 'json_object',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\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\t{\n\t\t\t\t\t\tdisplayName: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 360000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\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<OpenAICompatibleCredential>('openRouterApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tmaxRetries: number;\n\t\t\ttimeout: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttopP?: number;\n\t\t\tresponseFormat?: 'text' | 'json_object';\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tbaseURL: credentials.url,\n\t\t\thttpAgent: getHttpProxyAgent(),\n\t\t};\n\n\t\tconst model = new ChatOpenAI({\n\t\t\topenAIApiKey: credentials.apiKey,\n\t\t\tmodelName,\n\t\t\t...options,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tmodelKwargs: options.responseFormat\n\t\t\t\t? {\n\t\t\t\t\t\tresponse_format: { type: options.responseFormat },\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\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":[]}
@@ -23,6 +23,7 @@ __export(LmChatXAiGrok_node_exports, {
23
23
  module.exports = __toCommonJS(LmChatXAiGrok_node_exports);
24
24
  var import_openai = require("@langchain/openai");
25
25
  var import_n8n_workflow = require("n8n-workflow");
26
+ var import_httpProxyAgent = require("../../../utils/httpProxyAgent");
26
27
  var import_sharedFields = require("../../../utils/sharedFields");
27
28
  var import_error_handling = require("../../vendors/OpenAi/helpers/error-handling");
28
29
  var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler");
@@ -220,7 +221,8 @@ class LmChatXAiGrok {
220
221
  const modelName = this.getNodeParameter("model", itemIndex);
221
222
  const options = this.getNodeParameter("options", itemIndex, {});
222
223
  const configuration = {
223
- baseURL: credentials.url
224
+ baseURL: credentials.url,
225
+ httpAgent: (0, import_httpProxyAgent.getHttpProxyAgent)()
224
226
  };
225
227
  const model = new import_openai.ChatOpenAI({
226
228
  openAIApiKey: credentials.apiKey,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\n\nimport { ChatOpenAI, type ClientOptions } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatXAiGrok implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'xAI Grok Chat Model',\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-name-miscased\n\t\tname: 'lmChatXAiGrok',\n\t\ticon: { light: 'file:logo.dark.svg', dark: 'file:logo.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: 'xAI Grok 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.lmchatxaigrok/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'xAiApi',\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: '={{ $credentials?.url }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'If using JSON response format, you must include word \"json\" in the prompt in your chain or agent. Also, make sure to select latest models released post November 2023.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\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.x.ai/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: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'grok-2-vision-1212',\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Format',\n\t\t\t\t\t\tname: 'responseFormat',\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Regular text response',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\t\t\tvalue: 'json_object',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\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\t{\n\t\t\t\t\t\tdisplayName: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 360000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\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<OpenAICompatibleCredential>('xAiApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tmaxRetries: number;\n\t\t\ttimeout: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttopP?: number;\n\t\t\tresponseFormat?: 'text' | 'json_object';\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tbaseURL: credentials.url,\n\t\t};\n\n\t\tconst model = new ChatOpenAI({\n\t\t\topenAIApiKey: credentials.apiKey,\n\t\t\tmodelName,\n\t\t\t...options,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tmodelKwargs: {\n\t\t\t\tstream_options: undefined,\n\t\t\t\t...(options.responseFormat\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tresponse_format: { type: options.responseFormat },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined),\n\t\t\t},\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\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;AAEA,oBAA+C;AAC/C,0BAMO;AAEP,0BAA6C;AAE7C,4BAA2C;AAC3C,wCAA+C;AAC/C,2BAA8B;AAEvB,MAAM,cAAmC;AAAA,EAAzC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA;AAAA,MAEb,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,sBAAsB,MAAM,gBAAgB;AAAA,MAC3D,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,CAAC;AAAA,MACX,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;AAAA,MAEA,QAAQ,CAAC;AAAA;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,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,2BAA2B,CAAC,aAAa;AAAA,YAC1C;AAAA,UACD;AAAA,QACD;AAAA,QACA;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,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,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,EAAE;AAAA,cAC7D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,MAAM;AAAA,cACN,aAAa;AAAA,gBACZ,UAAU;AAAA,cACX;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,MAAM;AAAA,cACN,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,aACC;AAAA,gBACF;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,EAAE;AAAA,cAC7D,aACC;AAAA,cACD,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,YACA;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;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,eAA2C,QAAQ;AAElF,UAAM,YAAY,KAAK,iBAAiB,SAAS,SAAS;AAE1D,UAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAW9D,UAAM,gBAA+B;AAAA,MACpC,SAAS,YAAY;AAAA,IACtB;AAEA,UAAM,QAAQ,IAAI,yBAAW;AAAA,MAC5B,cAAc,YAAY;AAAA,MAC1B;AAAA,MACA,GAAG;AAAA,MACH,SAAS,QAAQ,WAAW;AAAA,MAC5B,YAAY,QAAQ,cAAc;AAAA,MAClC;AAAA,MACA,WAAW,CAAC,IAAI,mCAAc,IAAI,CAAC;AAAA,MACnC,aAAa;AAAA,QACZ,gBAAgB;AAAA,QAChB,GAAI,QAAQ,iBACT;AAAA,UACA,iBAAiB,EAAE,MAAM,QAAQ,eAAe;AAAA,QACjD,IACC;AAAA,MACJ;AAAA,MACA,qBAAiB,kEAA+B,MAAM,gDAA0B;AAAA,IACjF,CAAC;AAED,WAAO;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-dirname-against-convention */\n\nimport { ChatOpenAI, type ClientOptions } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getHttpProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nexport class LmChatXAiGrok implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'xAI Grok Chat Model',\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-name-miscased\n\t\tname: 'lmChatXAiGrok',\n\t\ticon: { light: 'file:logo.dark.svg', dark: 'file:logo.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: 'xAI Grok 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.lmchatxaigrok/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [],\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\toutputNames: ['Model'],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'xAiApi',\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: '={{ $credentials?.url }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'If using JSON response format, you must include word \"json\" in the prompt in your chain or agent. Also, make sure to select latest models released post November 2023.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\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.x.ai/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: '/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'grok-2-vision-1212',\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Format',\n\t\t\t\t\t\tname: 'responseFormat',\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Regular text response',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\t\t\tvalue: 'json_object',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\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\t{\n\t\t\t\t\t\tdisplayName: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 360000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\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<OpenAICompatibleCredential>('xAiApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tmaxRetries: number;\n\t\t\ttimeout: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttopP?: number;\n\t\t\tresponseFormat?: 'text' | 'json_object';\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tbaseURL: credentials.url,\n\t\t\thttpAgent: getHttpProxyAgent(),\n\t\t};\n\n\t\tconst model = new ChatOpenAI({\n\t\t\topenAIApiKey: credentials.apiKey,\n\t\t\tmodelName,\n\t\t\t...options,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tmodelKwargs: {\n\t\t\t\tstream_options: undefined,\n\t\t\t\t...(options.responseFormat\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tresponse_format: { type: options.responseFormat },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined),\n\t\t\t},\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\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":[]}
@@ -63,8 +63,8 @@ class McpTrigger extends import_n8n_workflow.Node {
63
63
  triggerPanel: {
64
64
  header: "Listen for MCP events",
65
65
  executionsHelp: {
66
- inactive: "This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'test step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. <a data-key='activate'>Activate</a> the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.",
67
- active: "This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'test step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor."
66
+ inactive: "This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. <a data-key='activate'>Activate</a> the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.",
67
+ active: "This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor."
68
68
  },
69
69
  activationHint: "Once you\u2019ve finished building your workflow, run it without having to click this button by using the production URL."
70
70
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/mcp/McpTrigger/McpTrigger.node.ts"],"sourcesContent":["import { WebhookAuthorizationError } from 'n8n-nodes-base/dist/nodes/Webhook/error';\nimport { validateWebhookAuthentication } from 'n8n-nodes-base/dist/nodes/Webhook/utils';\nimport type { INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';\nimport { NodeConnectionTypes, Node } from 'n8n-workflow';\n\nimport { getConnectedTools } from '@utils/helpers';\n\nimport type { CompressionResponse } from './FlushingSSEServerTransport';\nimport { McpServerSingleton } from './McpServer';\nimport type { McpServer } from './McpServer';\n\nconst MCP_SSE_SETUP_PATH = 'sse';\nconst MCP_SSE_MESSAGES_PATH = 'messages';\n\nexport class McpTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Server Trigger',\n\t\tname: 'mcpTrigger',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['trigger'],\n\t\tversion: 1,\n\t\tdescription: 'Expose n8n tools as an MCP Server endpoint',\n\t\tactivationMessage: 'You can now connect your MCP Clients to the SSE URL.',\n\t\tdefaults: {\n\t\t\tname: 'MCP Server Trigger',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI', 'Core Nodes'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Root Nodes', 'Model Context Protocol'],\n\t\t\t\t'Core Nodes': ['Other Trigger Nodes'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Server'],\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/core-nodes/n8n-nodes-langchain.mcptrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\ttriggerPanel: {\n\t\t\theader: 'Listen for MCP events',\n\t\t\texecutionsHelp: {\n\t\t\t\tinactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'test step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. <a data-key='activate'>Activate</a> the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t\tactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'test step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t},\n\t\t\tactivationHint:\n\t\t\t\t'Once you’ve finished building your workflow, run it without having to click this button by using the production URL.',\n\t\t},\n\t\tinputs: [\n\t\t\t{\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tdisplayName: 'Tools',\n\t\t\t},\n\t\t],\n\t\toutputs: [],\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\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{ name: 'None', value: 'none' },\n\t\t\t\t\t{ name: 'Bearer Auth', value: 'bearerAuth' },\n\t\t\t\t\t{ name: 'Header Auth', value: 'headerAuth' },\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Path',\n\t\t\t\tname: 'path',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'webhook',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The base path for this MCP server',\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}/${MCP_SSE_SETUP_PATH}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}/${MCP_SSE_MESSAGES_PATH}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync webhook(context: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst webhookName = context.getWebhookName();\n\t\tconst req = context.getRequestObject();\n\t\tconst resp = context.getResponseObject() as unknown as CompressionResponse;\n\n\t\ttry {\n\t\t\tawait validateWebhookAuthentication(context, 'authentication');\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookAuthorizationError) {\n\t\t\t\tresp.writeHead(error.responseCode);\n\t\t\t\tresp.end(error.message);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst mcpServer: McpServer = McpServerSingleton.instance(context.logger);\n\n\t\tif (webhookName === 'setup') {\n\t\t\t// Sets up the transport and opens the long-lived connection. This resp\n\t\t\t// will stay streaming, and is the channel that sends the events\n\t\t\tconst postUrl = req.path.replace(\n\t\t\t\tnew RegExp(`/${MCP_SSE_SETUP_PATH}$`),\n\t\t\t\t`/${MCP_SSE_MESSAGES_PATH}`,\n\t\t\t);\n\t\t\tawait mcpServer.connectTransport(postUrl, resp);\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t} else if (webhookName === 'default') {\n\t\t\t// This is the command-channel, and is actually executing the tools. This\n\t\t\t// sends the response back through the long-lived connection setup in the\n\t\t\t// 'setup' call\n\t\t\tconst connectedTools = await getConnectedTools(context, true);\n\n\t\t\tconst wasToolCall = await mcpServer.handlePostMessage(req, resp, connectedTools);\n\n\t\t\tif (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };\n\t\t\treturn { noWebhookResponse: true };\n\t\t}\n\n\t\treturn { workflowData: [[{ json: {} }]] };\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/mcp/McpTrigger/McpTrigger.node.ts"],"sourcesContent":["import { WebhookAuthorizationError } from 'n8n-nodes-base/dist/nodes/Webhook/error';\nimport { validateWebhookAuthentication } from 'n8n-nodes-base/dist/nodes/Webhook/utils';\nimport type { INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';\nimport { NodeConnectionTypes, Node } from 'n8n-workflow';\n\nimport { getConnectedTools } from '@utils/helpers';\n\nimport type { CompressionResponse } from './FlushingSSEServerTransport';\nimport { McpServerSingleton } from './McpServer';\nimport type { McpServer } from './McpServer';\n\nconst MCP_SSE_SETUP_PATH = 'sse';\nconst MCP_SSE_MESSAGES_PATH = 'messages';\n\nexport class McpTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Server Trigger',\n\t\tname: 'mcpTrigger',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['trigger'],\n\t\tversion: 1,\n\t\tdescription: 'Expose n8n tools as an MCP Server endpoint',\n\t\tactivationMessage: 'You can now connect your MCP Clients to the SSE URL.',\n\t\tdefaults: {\n\t\t\tname: 'MCP Server Trigger',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI', 'Core Nodes'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Root Nodes', 'Model Context Protocol'],\n\t\t\t\t'Core Nodes': ['Other Trigger Nodes'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Server'],\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/core-nodes/n8n-nodes-langchain.mcptrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\ttriggerPanel: {\n\t\t\theader: 'Listen for MCP events',\n\t\t\texecutionsHelp: {\n\t\t\t\tinactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. <a data-key='activate'>Activate</a> the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t\tactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t},\n\t\t\tactivationHint:\n\t\t\t\t'Once you’ve finished building your workflow, run it without having to click this button by using the production URL.',\n\t\t},\n\t\tinputs: [\n\t\t\t{\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tdisplayName: 'Tools',\n\t\t\t},\n\t\t],\n\t\toutputs: [],\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\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{ name: 'None', value: 'none' },\n\t\t\t\t\t{ name: 'Bearer Auth', value: 'bearerAuth' },\n\t\t\t\t\t{ name: 'Header Auth', value: 'headerAuth' },\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Path',\n\t\t\t\tname: 'path',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'webhook',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The base path for this MCP server',\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}/${MCP_SSE_SETUP_PATH}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}/${MCP_SSE_MESSAGES_PATH}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync webhook(context: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst webhookName = context.getWebhookName();\n\t\tconst req = context.getRequestObject();\n\t\tconst resp = context.getResponseObject() as unknown as CompressionResponse;\n\n\t\ttry {\n\t\t\tawait validateWebhookAuthentication(context, 'authentication');\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookAuthorizationError) {\n\t\t\t\tresp.writeHead(error.responseCode);\n\t\t\t\tresp.end(error.message);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst mcpServer: McpServer = McpServerSingleton.instance(context.logger);\n\n\t\tif (webhookName === 'setup') {\n\t\t\t// Sets up the transport and opens the long-lived connection. This resp\n\t\t\t// will stay streaming, and is the channel that sends the events\n\t\t\tconst postUrl = req.path.replace(\n\t\t\t\tnew RegExp(`/${MCP_SSE_SETUP_PATH}$`),\n\t\t\t\t`/${MCP_SSE_MESSAGES_PATH}`,\n\t\t\t);\n\t\t\tawait mcpServer.connectTransport(postUrl, resp);\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t} else if (webhookName === 'default') {\n\t\t\t// This is the command-channel, and is actually executing the tools. This\n\t\t\t// sends the response back through the long-lived connection setup in the\n\t\t\t// 'setup' call\n\t\t\tconst connectedTools = await getConnectedTools(context, true);\n\n\t\t\tconst wasToolCall = await mcpServer.handlePostMessage(req, resp, connectedTools);\n\n\t\t\tif (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };\n\t\t\treturn { noWebhookResponse: true };\n\t\t}\n\n\t\treturn { workflowData: [[{ json: {} }]] };\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -43,6 +43,7 @@ class ToolWorkflowV2 {
43
43
  const name = typeVersion <= 2.1 ? this.getNodeParameter("name", itemIndex) : (0, import_helpers.nodeNameToToolName)(node);
44
44
  const description = this.getNodeParameter("description", itemIndex);
45
45
  const tool = await workflowToolService.createTool({
46
+ ctx: this,
46
47
  name,
47
48
  description,
48
49
  itemIndex
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.ts"],"sourcesContent":["import type {\n\tINodeTypeBaseDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { nodeNameToToolName } from '@utils/helpers';\n\nimport { localResourceMapping } from './methods';\nimport { WorkflowToolService } from './utils/WorkflowToolService';\nimport { versionDescription } from './versionDescription';\n\nexport class ToolWorkflowV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\t...versionDescription,\n\t\t};\n\t}\n\n\tmethods = {\n\t\tlocalResourceMapping,\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst { typeVersion } = node;\n\t\tconst returnAllItems = typeVersion > 2;\n\n\t\tconst workflowToolService = new WorkflowToolService(this, { returnAllItems });\n\t\tconst name =\n\t\t\ttypeVersion <= 2.1\n\t\t\t\t? (this.getNodeParameter('name', itemIndex) as string)\n\t\t\t\t: nodeNameToToolName(node);\n\t\tconst description = this.getNodeParameter('description', itemIndex) as string;\n\n\t\tconst tool = await workflowToolService.createTool({\n\t\t\tname,\n\t\t\tdescription,\n\t\t\titemIndex,\n\t\t});\n\n\t\treturn { response: tool };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,qBAAmC;AAEnC,qBAAqC;AACrC,iCAAoC;AACpC,gCAAmC;AAE5B,MAAM,eAAoC;AAAA,EAGhD,YAAY,iBAA2C;AAOvD,mBAAU;AAAA,MACT;AAAA,IACD;AARC,SAAK,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,EACD;AAAA,EAMA,MAAM,WAAuC,WAAwC;AACpF,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,iBAAiB,cAAc;AAErC,UAAM,sBAAsB,IAAI,+CAAoB,MAAM,EAAE,eAAe,CAAC;AAC5E,UAAM,OACL,eAAe,MACX,KAAK,iBAAiB,QAAQ,SAAS,QACxC,mCAAmB,IAAI;AAC3B,UAAM,cAAc,KAAK,iBAAiB,eAAe,SAAS;AAElE,UAAM,OAAO,MAAM,oBAAoB,WAAW;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,WAAO,EAAE,UAAU,KAAK;AAAA,EACzB;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../../nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.ts"],"sourcesContent":["import type {\n\tINodeTypeBaseDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { nodeNameToToolName } from '@utils/helpers';\n\nimport { localResourceMapping } from './methods';\nimport { WorkflowToolService } from './utils/WorkflowToolService';\nimport { versionDescription } from './versionDescription';\n\nexport class ToolWorkflowV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\t...versionDescription,\n\t\t};\n\t}\n\n\tmethods = {\n\t\tlocalResourceMapping,\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst { typeVersion } = node;\n\t\tconst returnAllItems = typeVersion > 2;\n\n\t\tconst workflowToolService = new WorkflowToolService(this, { returnAllItems });\n\t\tconst name =\n\t\t\ttypeVersion <= 2.1\n\t\t\t\t? (this.getNodeParameter('name', itemIndex) as string)\n\t\t\t\t: nodeNameToToolName(node);\n\t\tconst description = this.getNodeParameter('description', itemIndex) as string;\n\n\t\tconst tool = await workflowToolService.createTool({\n\t\t\tctx: this,\n\t\t\tname,\n\t\t\tdescription,\n\t\t\titemIndex,\n\t\t});\n\n\t\treturn { response: tool };\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,qBAAmC;AAEnC,qBAAqC;AACrC,iCAAoC;AACpC,gCAAmC;AAE5B,MAAM,eAAoC;AAAA,EAGhD,YAAY,iBAA2C;AAOvD,mBAAU;AAAA,MACT;AAAA,IACD;AARC,SAAK,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,EACD;AAAA,EAMA,MAAM,WAAuC,WAAwC;AACpF,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,iBAAiB,cAAc;AAErC,UAAM,sBAAsB,IAAI,+CAAoB,MAAM,EAAE,eAAe,CAAC;AAC5E,UAAM,OACL,eAAe,MACX,KAAK,iBAAiB,QAAQ,SAAS,QACxC,mCAAmB,IAAI;AAC3B,UAAM,cAAc,KAAK,iBAAiB,eAAe,SAAS;AAElE,UAAM,OAAO,MAAM,oBAAoB,WAAW;AAAA,MACjD,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,WAAO,EAAE,UAAU,KAAK;AAAA,EACzB;AACD;","names":[]}
@@ -50,11 +50,12 @@ class WorkflowToolService {
50
50
  }
51
51
  // Creates the tool based on the provided parameters
52
52
  async createTool({
53
+ ctx,
53
54
  name,
54
55
  description,
55
56
  itemIndex
56
57
  }) {
57
- let runIndex = 0;
58
+ let runIndex = ctx.getNextRunIndex();
58
59
  const toolHandler = async (query, runManager) => {
59
60
  const localRunIndex = runIndex++;
60
61
  const context = this.baseContext.cloneWith({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.ts"],"sourcesContent":["import type { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { isArray, isObject } from 'lodash';\nimport type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces';\nimport * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode';\nimport { getCurrentWorkflowInputData } from 'n8n-nodes-base/dist/utils/workflowInputsResourceMapping/GenericFunctions';\nimport type {\n\tExecuteWorkflowData,\n\tExecutionError,\n\tFromAIArgument,\n\tIDataObject,\n\tIExecuteWorkflowInfo,\n\tINodeExecutionData,\n\tINodeParameterResourceLocator,\n\tISupplyDataFunctions,\n\tITaskMetadata,\n\tIWorkflowBase,\n\tIWorkflowDataProxyData,\n\tResourceMapperValue,\n} from 'n8n-workflow';\nimport {\n\tgenerateZodSchema,\n\tjsonParse,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tparseErrorMetadata,\n\ttraverseNodeParameters,\n} from 'n8n-workflow';\nimport { z } from 'zod';\n\nfunction isNodeExecutionData(data: unknown): data is INodeExecutionData[] {\n\treturn isArray(data) && Boolean(data.length) && isObject(data[0]) && 'json' in data[0];\n}\n\n/**\n\tMain class for creating the Workflow tool\n\tProcesses the node parameters and creates AI Agent tool capable of executing n8n workflows\n*/\nexport class WorkflowToolService {\n\t// Determines if we should use input schema when creating the tool\n\tprivate useSchema: boolean;\n\n\t// Sub-workflow id, pulled from referenced sub-workflow\n\tprivate subWorkflowId: string | undefined;\n\n\t// Sub-workflow execution id, will be set after the sub-workflow is executed\n\tprivate subExecutionId: string | undefined;\n\n\tprivate returnAllItems: boolean = false;\n\n\tconstructor(\n\t\tprivate baseContext: ISupplyDataFunctions,\n\t\toptions?: { returnAllItems: boolean },\n\t) {\n\t\tconst subWorkflowInputs = this.baseContext.getNode().parameters\n\t\t\t.workflowInputs as ResourceMapperValue;\n\t\tthis.useSchema = (subWorkflowInputs?.schema ?? []).length > 0;\n\t\tthis.returnAllItems = options?.returnAllItems ?? false;\n\t}\n\n\t// Creates the tool based on the provided parameters\n\tasync createTool({\n\t\tname,\n\t\tdescription,\n\t\titemIndex,\n\t}: {\n\t\tname: string;\n\t\tdescription: string;\n\t\titemIndex: number;\n\t}): Promise<DynamicTool | DynamicStructuredTool> {\n\t\tlet runIndex = 0;\n\t\t// Handler for the tool execution, will be called when the tool is executed\n\t\t// This function will execute the sub-workflow and return the response\n\t\tconst toolHandler = async (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t): Promise<IDataObject | IDataObject[] | string> => {\n\t\t\tconst localRunIndex = runIndex++;\n\t\t\t// We need to clone the context here to handle runIndex correctly\n\t\t\t// Otherwise the runIndex will be shared between different executions\n\t\t\t// Causing incorrect data to be passed to the sub-workflow and via $fromAI\n\t\t\tconst context = this.baseContext.cloneWith({\n\t\t\t\trunIndex: localRunIndex,\n\t\t\t\tinputData: [[{ json: { query } }]],\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst response = await this.runFunction(context, query, itemIndex, runManager);\n\n\t\t\t\tconst processedResponse = this.handleToolResponse(response);\n\n\t\t\t\tlet responseData: INodeExecutionData[];\n\t\t\t\tif (isNodeExecutionData(response)) {\n\t\t\t\t\tresponseData = response;\n\t\t\t\t} else {\n\t\t\t\t\tconst reParsedData = jsonParse<IDataObject>(processedResponse, {\n\t\t\t\t\t\tfallbackValue: { response: processedResponse },\n\t\t\t\t\t});\n\n\t\t\t\t\tresponseData = [{ json: reParsedData }];\n\t\t\t\t}\n\n\t\t\t\t// Once the sub-workflow is executed, add the output data to the context\n\t\t\t\t// This will be used to link the sub-workflow execution in the parent workflow\n\t\t\t\tlet metadata: ITaskMetadata | undefined;\n\t\t\t\tif (this.subExecutionId && this.subWorkflowId) {\n\t\t\t\t\tmetadata = {\n\t\t\t\t\t\tsubExecution: {\n\t\t\t\t\t\t\texecutionId: this.subExecutionId,\n\t\t\t\t\t\t\tworkflowId: this.subWorkflowId,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t[responseData],\n\t\t\t\t\tmetadata,\n\t\t\t\t);\n\n\t\t\t\treturn processedResponse;\n\t\t\t} catch (error) {\n\t\t\t\tconst executionError = error as ExecutionError;\n\t\t\t\tconst errorResponse = `There was an error: \"${executionError.message}\"`;\n\n\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\texecutionError,\n\t\t\t\t\tmetadata,\n\t\t\t\t);\n\t\t\t\treturn errorResponse;\n\t\t\t}\n\t\t};\n\n\t\t// Create structured tool if input schema is provided\n\t\treturn this.useSchema\n\t\t\t? await this.createStructuredTool(name, description, toolHandler)\n\t\t\t: new DynamicTool({ name, description, func: toolHandler });\n\t}\n\n\tprivate handleToolResponse(response: unknown): string {\n\t\tif (typeof response === 'number') {\n\t\t\treturn response.toString();\n\t\t}\n\n\t\tif (isNodeExecutionData(response)) {\n\t\t\treturn JSON.stringify(\n\t\t\t\tresponse.map((item) => item.json),\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t);\n\t\t}\n\n\t\tif (isObject(response)) {\n\t\t\treturn JSON.stringify(response, null, 2);\n\t\t}\n\n\t\tif (typeof response !== 'string') {\n\t\t\tthrow new NodeOperationError(this.baseContext.getNode(), 'Wrong output type returned', {\n\t\t\t\tdescription: `The response property should be a string, but it is an ${typeof response}`,\n\t\t\t});\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Executes specified sub-workflow with provided inputs\n\t */\n\tprivate async executeSubWorkflow(\n\t\tcontext: ISupplyDataFunctions,\n\t\tworkflowInfo: IExecuteWorkflowInfo,\n\t\titems: INodeExecutionData[],\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<{ response: string | IDataObject | INodeExecutionData[]; subExecutionId: string }> {\n\t\tlet receivedData: ExecuteWorkflowData;\n\t\ttry {\n\t\t\treceivedData = await context.executeWorkflow(workflowInfo, items, runManager?.getChild(), {\n\t\t\t\tparentExecution: {\n\t\t\t\t\texecutionId: workflowProxy.$execution.id,\n\t\t\t\t\tworkflowId: workflowProxy.$workflow.id,\n\t\t\t\t},\n\t\t\t});\n\t\t\t// Set sub-workflow execution id so it can be used in other places\n\t\t\tthis.subExecutionId = receivedData.executionId;\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(context.getNode(), error as Error);\n\t\t}\n\n\t\tlet response: IDataObject | INodeExecutionData[] | undefined;\n\t\tif (this.returnAllItems) {\n\t\t\tresponse = receivedData?.data?.[0]?.length ? receivedData.data[0] : undefined;\n\t\t} else {\n\t\t\tresponse = receivedData?.data?.[0]?.[0]?.json;\n\t\t}\n\t\tif (response === undefined) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'There was an error: \"The workflow did not return a response\"',\n\t\t\t);\n\t\t}\n\n\t\treturn { response, subExecutionId: receivedData.executionId };\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source and executes it.\n\t * This function will be called as part of the tool execution (from the toolHandler)\n\t */\n\tprivate async runFunction(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<string | IDataObject | INodeExecutionData[]> {\n\t\tconst source = context.getNodeParameter('source', itemIndex) as string;\n\t\tconst workflowProxy = context.getWorkflowDataProxy(0);\n\n\t\tconst { workflowInfo } = await this.getSubWorkflowInfo(\n\t\t\tcontext,\n\t\t\tsource,\n\t\t\titemIndex,\n\t\t\tworkflowProxy,\n\t\t);\n\t\tconst rawData = this.prepareRawData(context, query, itemIndex);\n\t\tconst items = await this.prepareWorkflowItems(context, query, itemIndex, rawData);\n\n\t\tthis.subWorkflowId = workflowInfo.id;\n\n\t\tconst { response } = await this.executeSubWorkflow(\n\t\t\tcontext,\n\t\t\tworkflowInfo,\n\t\t\titems,\n\t\t\tworkflowProxy,\n\t\t\trunManager,\n\t\t);\n\t\treturn response;\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source (database or parameter)\n\t */\n\tprivate async getSubWorkflowInfo(\n\t\tcontext: ISupplyDataFunctions,\n\t\tsource: string,\n\t\titemIndex: number,\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t): Promise<{\n\t\tworkflowInfo: IExecuteWorkflowInfo;\n\t\tsubWorkflowId: string;\n\t}> {\n\t\tconst workflowInfo: IExecuteWorkflowInfo = {};\n\t\tlet subWorkflowId: string;\n\n\t\tif (source === 'database') {\n\t\t\tconst { value } = context.getNodeParameter(\n\t\t\t\t'workflowId',\n\t\t\t\titemIndex,\n\t\t\t\t{},\n\t\t\t) as INodeParameterResourceLocator;\n\t\t\tworkflowInfo.id = value as string;\n\t\t\tsubWorkflowId = workflowInfo.id;\n\t\t} else if (source === 'parameter') {\n\t\t\tconst workflowJson = context.getNodeParameter('workflowJson', itemIndex) as string;\n\t\t\ttry {\n\t\t\t\tworkflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase;\n\t\t\t\t// subworkflow is same as parent workflow\n\t\t\t\tsubWorkflowId = workflowProxy.$workflow.id;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`The provided workflow is not valid JSON: \"${(error as Error).message}\"`,\n\t\t\t\t\t{ itemIndex },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn { workflowInfo, subWorkflowId: subWorkflowId! };\n\t}\n\n\tprivate prepareRawData(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t): IDataObject {\n\t\tconst rawData: IDataObject = { query };\n\t\tconst workflowFieldsJson = context.getNodeParameter('fields.values', itemIndex, [], {\n\t\t\trawExpressions: true,\n\t\t}) as SetField[];\n\n\t\t// Copied from Set Node v2\n\t\tfor (const entry of workflowFieldsJson) {\n\t\t\tif (entry.type === 'objectValue' && (entry.objectValue as string).startsWith('=')) {\n\t\t\t\trawData[entry.name] = (entry.objectValue as string).replace(/^=+/, '');\n\t\t\t}\n\t\t}\n\n\t\treturn rawData;\n\t}\n\n\t/**\n\t * Prepares the sub-workflow items for execution\n\t */\n\tprivate async prepareWorkflowItems(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trawData: IDataObject,\n\t): Promise<INodeExecutionData[]> {\n\t\tconst options: SetNodeOptions = { include: 'all' };\n\t\tlet jsonData = typeof query === 'object' ? query : { query };\n\n\t\tif (this.useSchema) {\n\t\t\tconst currentWorkflowInputs = getCurrentWorkflowInputData.call(context);\n\t\t\tjsonData = currentWorkflowInputs[itemIndex].json;\n\t\t}\n\n\t\tconst newItem = await manual.execute.call(\n\t\t\tcontext,\n\t\t\t{ json: jsonData },\n\t\t\titemIndex,\n\t\t\toptions,\n\t\t\trawData,\n\t\t\tcontext.getNode(),\n\t\t);\n\n\t\treturn [newItem] as INodeExecutionData[];\n\t}\n\n\t/**\n\t * Create structured tool by parsing the sub-workflow input schema\n\t */\n\tprivate async createStructuredTool(\n\t\tname: string,\n\t\tdescription: string,\n\t\tfunc: (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t) => Promise<string | IDataObject | IDataObject[]>,\n\t): Promise<DynamicStructuredTool | DynamicTool> {\n\t\tconst collectedArguments = await this.extractFromAIParameters();\n\n\t\t// If there are no `fromAI` arguments, fallback to creating a simple tool\n\t\tif (collectedArguments.length === 0) {\n\t\t\treturn new DynamicTool({ name, description, func });\n\t\t}\n\n\t\t// Otherwise, prepare Zod schema and create a structured tool\n\t\tconst schema = this.createZodSchema(collectedArguments);\n\t\treturn new DynamicStructuredTool({ schema, name, description, func });\n\t}\n\n\tprivate async extractFromAIParameters(): Promise<FromAIArgument[]> {\n\t\tconst collectedArguments: FromAIArgument[] = [];\n\t\ttraverseNodeParameters(this.baseContext.getNode().parameters, collectedArguments);\n\n\t\tconst uniqueArgsMap = new Map<string, FromAIArgument>();\n\t\tfor (const arg of collectedArguments) {\n\t\t\tuniqueArgsMap.set(arg.key, arg);\n\t\t}\n\n\t\treturn Array.from(uniqueArgsMap.values());\n\t}\n\n\tprivate createZodSchema(args: FromAIArgument[]): z.ZodObject<any> {\n\t\tconst schemaObj = args.reduce((acc: Record<string, z.ZodTypeAny>, placeholder) => {\n\t\t\tacc[placeholder.key] = generateZodSchema(placeholder);\n\t\t\treturn acc;\n\t\t}, {});\n\n\t\treturn z.object(schemaObj).required();\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.ts"],"sourcesContent":["import type { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { isArray, isObject } from 'lodash';\nimport type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces';\nimport * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode';\nimport { getCurrentWorkflowInputData } from 'n8n-nodes-base/dist/utils/workflowInputsResourceMapping/GenericFunctions';\nimport type {\n\tExecuteWorkflowData,\n\tExecutionError,\n\tFromAIArgument,\n\tIDataObject,\n\tIExecuteWorkflowInfo,\n\tINodeExecutionData,\n\tINodeParameterResourceLocator,\n\tISupplyDataFunctions,\n\tITaskMetadata,\n\tIWorkflowBase,\n\tIWorkflowDataProxyData,\n\tResourceMapperValue,\n} from 'n8n-workflow';\nimport {\n\tgenerateZodSchema,\n\tjsonParse,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tparseErrorMetadata,\n\ttraverseNodeParameters,\n} from 'n8n-workflow';\nimport { z } from 'zod';\n\nfunction isNodeExecutionData(data: unknown): data is INodeExecutionData[] {\n\treturn isArray(data) && Boolean(data.length) && isObject(data[0]) && 'json' in data[0];\n}\n\n/**\n\tMain class for creating the Workflow tool\n\tProcesses the node parameters and creates AI Agent tool capable of executing n8n workflows\n*/\nexport class WorkflowToolService {\n\t// Determines if we should use input schema when creating the tool\n\tprivate useSchema: boolean;\n\n\t// Sub-workflow id, pulled from referenced sub-workflow\n\tprivate subWorkflowId: string | undefined;\n\n\t// Sub-workflow execution id, will be set after the sub-workflow is executed\n\tprivate subExecutionId: string | undefined;\n\n\tprivate returnAllItems: boolean = false;\n\n\tconstructor(\n\t\tprivate baseContext: ISupplyDataFunctions,\n\t\toptions?: { returnAllItems: boolean },\n\t) {\n\t\tconst subWorkflowInputs = this.baseContext.getNode().parameters\n\t\t\t.workflowInputs as ResourceMapperValue;\n\t\tthis.useSchema = (subWorkflowInputs?.schema ?? []).length > 0;\n\t\tthis.returnAllItems = options?.returnAllItems ?? false;\n\t}\n\n\t// Creates the tool based on the provided parameters\n\tasync createTool({\n\t\tctx,\n\t\tname,\n\t\tdescription,\n\t\titemIndex,\n\t}: {\n\t\tctx: ISupplyDataFunctions;\n\t\tname: string;\n\t\tdescription: string;\n\t\titemIndex: number;\n\t}): Promise<DynamicTool | DynamicStructuredTool> {\n\t\t// Handler for the tool execution, will be called when the tool is executed\n\t\t// This function will execute the sub-workflow and return the response\n\t\t// We get the runIndex from the context to handle multiple executions\n\t\t// of the same tool when the tool is used in a loop or in a parallel execution.\n\t\tlet runIndex: number = ctx.getNextRunIndex();\n\t\tconst toolHandler = async (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t): Promise<IDataObject | IDataObject[] | string> => {\n\t\t\tconst localRunIndex = runIndex++;\n\t\t\t// We need to clone the context here to handle runIndex correctly\n\t\t\t// Otherwise the runIndex will be shared between different executions\n\t\t\t// Causing incorrect data to be passed to the sub-workflow and via $fromAI\n\t\t\tconst context = this.baseContext.cloneWith({\n\t\t\t\trunIndex: localRunIndex,\n\t\t\t\tinputData: [[{ json: { query } }]],\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst response = await this.runFunction(context, query, itemIndex, runManager);\n\n\t\t\t\tconst processedResponse = this.handleToolResponse(response);\n\n\t\t\t\tlet responseData: INodeExecutionData[];\n\t\t\t\tif (isNodeExecutionData(response)) {\n\t\t\t\t\tresponseData = response;\n\t\t\t\t} else {\n\t\t\t\t\tconst reParsedData = jsonParse<IDataObject>(processedResponse, {\n\t\t\t\t\t\tfallbackValue: { response: processedResponse },\n\t\t\t\t\t});\n\n\t\t\t\t\tresponseData = [{ json: reParsedData }];\n\t\t\t\t}\n\n\t\t\t\t// Once the sub-workflow is executed, add the output data to the context\n\t\t\t\t// This will be used to link the sub-workflow execution in the parent workflow\n\t\t\t\tlet metadata: ITaskMetadata | undefined;\n\t\t\t\tif (this.subExecutionId && this.subWorkflowId) {\n\t\t\t\t\tmetadata = {\n\t\t\t\t\t\tsubExecution: {\n\t\t\t\t\t\t\texecutionId: this.subExecutionId,\n\t\t\t\t\t\t\tworkflowId: this.subWorkflowId,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\t[responseData],\n\t\t\t\t\tmetadata,\n\t\t\t\t);\n\n\t\t\t\treturn processedResponse;\n\t\t\t} catch (error) {\n\t\t\t\tconst executionError = error as ExecutionError;\n\t\t\t\tconst errorResponse = `There was an error: \"${executionError.message}\"`;\n\n\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\tvoid context.addOutputData(\n\t\t\t\t\tNodeConnectionTypes.AiTool,\n\t\t\t\t\tlocalRunIndex,\n\t\t\t\t\texecutionError,\n\t\t\t\t\tmetadata,\n\t\t\t\t);\n\t\t\t\treturn errorResponse;\n\t\t\t}\n\t\t};\n\n\t\t// Create structured tool if input schema is provided\n\t\treturn this.useSchema\n\t\t\t? await this.createStructuredTool(name, description, toolHandler)\n\t\t\t: new DynamicTool({ name, description, func: toolHandler });\n\t}\n\n\tprivate handleToolResponse(response: unknown): string {\n\t\tif (typeof response === 'number') {\n\t\t\treturn response.toString();\n\t\t}\n\n\t\tif (isNodeExecutionData(response)) {\n\t\t\treturn JSON.stringify(\n\t\t\t\tresponse.map((item) => item.json),\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t);\n\t\t}\n\n\t\tif (isObject(response)) {\n\t\t\treturn JSON.stringify(response, null, 2);\n\t\t}\n\n\t\tif (typeof response !== 'string') {\n\t\t\tthrow new NodeOperationError(this.baseContext.getNode(), 'Wrong output type returned', {\n\t\t\t\tdescription: `The response property should be a string, but it is an ${typeof response}`,\n\t\t\t});\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Executes specified sub-workflow with provided inputs\n\t */\n\tprivate async executeSubWorkflow(\n\t\tcontext: ISupplyDataFunctions,\n\t\tworkflowInfo: IExecuteWorkflowInfo,\n\t\titems: INodeExecutionData[],\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<{ response: string | IDataObject | INodeExecutionData[]; subExecutionId: string }> {\n\t\tlet receivedData: ExecuteWorkflowData;\n\t\ttry {\n\t\t\treceivedData = await context.executeWorkflow(workflowInfo, items, runManager?.getChild(), {\n\t\t\t\tparentExecution: {\n\t\t\t\t\texecutionId: workflowProxy.$execution.id,\n\t\t\t\t\tworkflowId: workflowProxy.$workflow.id,\n\t\t\t\t},\n\t\t\t});\n\t\t\t// Set sub-workflow execution id so it can be used in other places\n\t\t\tthis.subExecutionId = receivedData.executionId;\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(context.getNode(), error as Error);\n\t\t}\n\n\t\tlet response: IDataObject | INodeExecutionData[] | undefined;\n\t\tif (this.returnAllItems) {\n\t\t\tresponse = receivedData?.data?.[0]?.length ? receivedData.data[0] : undefined;\n\t\t} else {\n\t\t\tresponse = receivedData?.data?.[0]?.[0]?.json;\n\t\t}\n\t\tif (response === undefined) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'There was an error: \"The workflow did not return a response\"',\n\t\t\t);\n\t\t}\n\n\t\treturn { response, subExecutionId: receivedData.executionId };\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source and executes it.\n\t * This function will be called as part of the tool execution (from the toolHandler)\n\t */\n\tprivate async runFunction(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trunManager?: CallbackManagerForToolRun,\n\t): Promise<string | IDataObject | INodeExecutionData[]> {\n\t\tconst source = context.getNodeParameter('source', itemIndex) as string;\n\t\tconst workflowProxy = context.getWorkflowDataProxy(0);\n\n\t\tconst { workflowInfo } = await this.getSubWorkflowInfo(\n\t\t\tcontext,\n\t\t\tsource,\n\t\t\titemIndex,\n\t\t\tworkflowProxy,\n\t\t);\n\t\tconst rawData = this.prepareRawData(context, query, itemIndex);\n\t\tconst items = await this.prepareWorkflowItems(context, query, itemIndex, rawData);\n\n\t\tthis.subWorkflowId = workflowInfo.id;\n\n\t\tconst { response } = await this.executeSubWorkflow(\n\t\t\tcontext,\n\t\t\tworkflowInfo,\n\t\t\titems,\n\t\t\tworkflowProxy,\n\t\t\trunManager,\n\t\t);\n\t\treturn response;\n\t}\n\n\t/**\n\t * Gets the sub-workflow info based on the source (database or parameter)\n\t */\n\tprivate async getSubWorkflowInfo(\n\t\tcontext: ISupplyDataFunctions,\n\t\tsource: string,\n\t\titemIndex: number,\n\t\tworkflowProxy: IWorkflowDataProxyData,\n\t): Promise<{\n\t\tworkflowInfo: IExecuteWorkflowInfo;\n\t\tsubWorkflowId: string;\n\t}> {\n\t\tconst workflowInfo: IExecuteWorkflowInfo = {};\n\t\tlet subWorkflowId: string;\n\n\t\tif (source === 'database') {\n\t\t\tconst { value } = context.getNodeParameter(\n\t\t\t\t'workflowId',\n\t\t\t\titemIndex,\n\t\t\t\t{},\n\t\t\t) as INodeParameterResourceLocator;\n\t\t\tworkflowInfo.id = value as string;\n\t\t\tsubWorkflowId = workflowInfo.id;\n\t\t} else if (source === 'parameter') {\n\t\t\tconst workflowJson = context.getNodeParameter('workflowJson', itemIndex) as string;\n\t\t\ttry {\n\t\t\t\tworkflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase;\n\t\t\t\t// subworkflow is same as parent workflow\n\t\t\t\tsubWorkflowId = workflowProxy.$workflow.id;\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`The provided workflow is not valid JSON: \"${(error as Error).message}\"`,\n\t\t\t\t\t{ itemIndex },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn { workflowInfo, subWorkflowId: subWorkflowId! };\n\t}\n\n\tprivate prepareRawData(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t): IDataObject {\n\t\tconst rawData: IDataObject = { query };\n\t\tconst workflowFieldsJson = context.getNodeParameter('fields.values', itemIndex, [], {\n\t\t\trawExpressions: true,\n\t\t}) as SetField[];\n\n\t\t// Copied from Set Node v2\n\t\tfor (const entry of workflowFieldsJson) {\n\t\t\tif (entry.type === 'objectValue' && (entry.objectValue as string).startsWith('=')) {\n\t\t\t\trawData[entry.name] = (entry.objectValue as string).replace(/^=+/, '');\n\t\t\t}\n\t\t}\n\n\t\treturn rawData;\n\t}\n\n\t/**\n\t * Prepares the sub-workflow items for execution\n\t */\n\tprivate async prepareWorkflowItems(\n\t\tcontext: ISupplyDataFunctions,\n\t\tquery: string | IDataObject,\n\t\titemIndex: number,\n\t\trawData: IDataObject,\n\t): Promise<INodeExecutionData[]> {\n\t\tconst options: SetNodeOptions = { include: 'all' };\n\t\tlet jsonData = typeof query === 'object' ? query : { query };\n\n\t\tif (this.useSchema) {\n\t\t\tconst currentWorkflowInputs = getCurrentWorkflowInputData.call(context);\n\t\t\tjsonData = currentWorkflowInputs[itemIndex].json;\n\t\t}\n\n\t\tconst newItem = await manual.execute.call(\n\t\t\tcontext,\n\t\t\t{ json: jsonData },\n\t\t\titemIndex,\n\t\t\toptions,\n\t\t\trawData,\n\t\t\tcontext.getNode(),\n\t\t);\n\n\t\treturn [newItem] as INodeExecutionData[];\n\t}\n\n\t/**\n\t * Create structured tool by parsing the sub-workflow input schema\n\t */\n\tprivate async createStructuredTool(\n\t\tname: string,\n\t\tdescription: string,\n\t\tfunc: (\n\t\t\tquery: string | IDataObject,\n\t\t\trunManager?: CallbackManagerForToolRun,\n\t\t) => Promise<string | IDataObject | IDataObject[]>,\n\t): Promise<DynamicStructuredTool | DynamicTool> {\n\t\tconst collectedArguments = await this.extractFromAIParameters();\n\n\t\t// If there are no `fromAI` arguments, fallback to creating a simple tool\n\t\tif (collectedArguments.length === 0) {\n\t\t\treturn new DynamicTool({ name, description, func });\n\t\t}\n\n\t\t// Otherwise, prepare Zod schema and create a structured tool\n\t\tconst schema = this.createZodSchema(collectedArguments);\n\t\treturn new DynamicStructuredTool({ schema, name, description, func });\n\t}\n\n\tprivate async extractFromAIParameters(): Promise<FromAIArgument[]> {\n\t\tconst collectedArguments: FromAIArgument[] = [];\n\t\ttraverseNodeParameters(this.baseContext.getNode().parameters, collectedArguments);\n\n\t\tconst uniqueArgsMap = new Map<string, FromAIArgument>();\n\t\tfor (const arg of collectedArguments) {\n\t\t\tuniqueArgsMap.set(arg.key, arg);\n\t\t}\n\n\t\treturn Array.from(uniqueArgsMap.values());\n\t}\n\n\tprivate createZodSchema(args: FromAIArgument[]): z.ZodObject<any> {\n\t\tconst schemaObj = args.reduce((acc: Record<string, z.ZodTypeAny>, placeholder) => {\n\t\t\tacc[placeholder.key] = generateZodSchema(placeholder);\n\t\t\treturn acc;\n\t\t}, {});\n\n\t\treturn z.object(schemaObj).required();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAmD;AACnD,oBAAkC;AAElC,aAAwB;AACxB,8BAA4C;AAe5C,0BAOO;AACP,iBAAkB;AAElB,SAAS,oBAAoB,MAA6C;AACzE,aAAO,uBAAQ,IAAI,KAAK,QAAQ,KAAK,MAAM,SAAK,wBAAS,KAAK,CAAC,CAAC,KAAK,UAAU,KAAK,CAAC;AACtF;AAMO,MAAM,oBAAoB;AAAA,EAYhC,YACS,aACR,SACC;AAFO;AAHT,SAAQ,iBAA0B;AAMjC,UAAM,oBAAoB,KAAK,YAAY,QAAQ,EAAE,WACnD;AACF,SAAK,aAAa,mBAAmB,UAAU,CAAC,GAAG,SAAS;AAC5D,SAAK,iBAAiB,SAAS,kBAAkB;AAAA,EAClD;AAAA;AAAA,EAGA,MAAM,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,GAKiD;AAKhD,QAAI,WAAmB,IAAI,gBAAgB;AAC3C,UAAM,cAAc,OACnB,OACA,eACmD;AACnD,YAAM,gBAAgB;AAItB,YAAM,UAAU,KAAK,YAAY,UAAU;AAAA,QAC1C,UAAU;AAAA,QACV,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAAA,MAClC,CAAC;AAED,UAAI;AACH,cAAM,WAAW,MAAM,KAAK,YAAY,SAAS,OAAO,WAAW,UAAU;AAE7E,cAAM,oBAAoB,KAAK,mBAAmB,QAAQ;AAE1D,YAAI;AACJ,YAAI,oBAAoB,QAAQ,GAAG;AAClC,yBAAe;AAAA,QAChB,OAAO;AACN,gBAAM,mBAAe,+BAAuB,mBAAmB;AAAA,YAC9D,eAAe,EAAE,UAAU,kBAAkB;AAAA,UAC9C,CAAC;AAED,yBAAe,CAAC,EAAE,MAAM,aAAa,CAAC;AAAA,QACvC;AAIA,YAAI;AACJ,YAAI,KAAK,kBAAkB,KAAK,eAAe;AAC9C,qBAAW;AAAA,YACV,cAAc;AAAA,cACb,aAAa,KAAK;AAAA,cAClB,YAAY,KAAK;AAAA,YAClB;AAAA,UACD;AAAA,QACD;AAEA,aAAK,QAAQ;AAAA,UACZ,wCAAoB;AAAA,UACpB;AAAA,UACA,CAAC,YAAY;AAAA,UACb;AAAA,QACD;AAEA,eAAO;AAAA,MACR,SAAS,OAAO;AACf,cAAM,iBAAiB;AACvB,cAAM,gBAAgB,wBAAwB,eAAe,OAAO;AAEpE,cAAM,eAAW,wCAAmB,KAAK;AACzC,aAAK,QAAQ;AAAA,UACZ,wCAAoB;AAAA,UACpB;AAAA,UACA;AAAA,UACA;AAAA,QACD;AACA,eAAO;AAAA,MACR;AAAA,IACD;AAGA,WAAO,KAAK,YACT,MAAM,KAAK,qBAAqB,MAAM,aAAa,WAAW,IAC9D,IAAI,yBAAY,EAAE,MAAM,aAAa,MAAM,YAAY,CAAC;AAAA,EAC5D;AAAA,EAEQ,mBAAmB,UAA2B;AACrD,QAAI,OAAO,aAAa,UAAU;AACjC,aAAO,SAAS,SAAS;AAAA,IAC1B;AAEA,QAAI,oBAAoB,QAAQ,GAAG;AAClC,aAAO,KAAK;AAAA,QACX,SAAS,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,QAChC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,YAAI,wBAAS,QAAQ,GAAG;AACvB,aAAO,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,IACxC;AAEA,QAAI,OAAO,aAAa,UAAU;AACjC,YAAM,IAAI,uCAAmB,KAAK,YAAY,QAAQ,GAAG,8BAA8B;AAAA,QACtF,aAAa,0DAA0D,OAAO,QAAQ;AAAA,MACvF,CAAC;AAAA,IACF;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBACb,SACA,cACA,OACA,eACA,YAC6F;AAC7F,QAAI;AACJ,QAAI;AACH,qBAAe,MAAM,QAAQ,gBAAgB,cAAc,OAAO,YAAY,SAAS,GAAG;AAAA,QACzF,iBAAiB;AAAA,UAChB,aAAa,cAAc,WAAW;AAAA,UACtC,YAAY,cAAc,UAAU;AAAA,QACrC;AAAA,MACD,CAAC;AAED,WAAK,iBAAiB,aAAa;AAAA,IACpC,SAAS,OAAO;AACf,YAAM,IAAI,uCAAmB,QAAQ,QAAQ,GAAG,KAAc;AAAA,IAC/D;AAEA,QAAI;AACJ,QAAI,KAAK,gBAAgB;AACxB,iBAAW,cAAc,OAAO,CAAC,GAAG,SAAS,aAAa,KAAK,CAAC,IAAI;AAAA,IACrE,OAAO;AACN,iBAAW,cAAc,OAAO,CAAC,IAAI,CAAC,GAAG;AAAA,IAC1C;AACA,QAAI,aAAa,QAAW;AAC3B,YAAM,IAAI;AAAA,QACT,QAAQ,QAAQ;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAEA,WAAO,EAAE,UAAU,gBAAgB,aAAa,YAAY;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YACb,SACA,OACA,WACA,YACuD;AACvD,UAAM,SAAS,QAAQ,iBAAiB,UAAU,SAAS;AAC3D,UAAM,gBAAgB,QAAQ,qBAAqB,CAAC;AAEpD,UAAM,EAAE,aAAa,IAAI,MAAM,KAAK;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,UAAM,UAAU,KAAK,eAAe,SAAS,OAAO,SAAS;AAC7D,UAAM,QAAQ,MAAM,KAAK,qBAAqB,SAAS,OAAO,WAAW,OAAO;AAEhF,SAAK,gBAAgB,aAAa;AAElC,UAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBACb,SACA,QACA,WACA,eAIE;AACF,UAAM,eAAqC,CAAC;AAC5C,QAAI;AAEJ,QAAI,WAAW,YAAY;AAC1B,YAAM,EAAE,MAAM,IAAI,QAAQ;AAAA,QACzB;AAAA,QACA;AAAA,QACA,CAAC;AAAA,MACF;AACA,mBAAa,KAAK;AAClB,sBAAgB,aAAa;AAAA,IAC9B,WAAW,WAAW,aAAa;AAClC,YAAM,eAAe,QAAQ,iBAAiB,gBAAgB,SAAS;AACvE,UAAI;AACH,qBAAa,OAAO,KAAK,MAAM,YAAY;AAE3C,wBAAgB,cAAc,UAAU;AAAA,MACzC,SAAS,OAAO;AACf,cAAM,IAAI;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,6CAA8C,MAAgB,OAAO;AAAA,UACrE,EAAE,UAAU;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAEA,WAAO,EAAE,cAAc,cAA8B;AAAA,EACtD;AAAA,EAEQ,eACP,SACA,OACA,WACc;AACd,UAAM,UAAuB,EAAE,MAAM;AACrC,UAAM,qBAAqB,QAAQ,iBAAiB,iBAAiB,WAAW,CAAC,GAAG;AAAA,MACnF,gBAAgB;AAAA,IACjB,CAAC;AAGD,eAAW,SAAS,oBAAoB;AACvC,UAAI,MAAM,SAAS,iBAAkB,MAAM,YAAuB,WAAW,GAAG,GAAG;AAClF,gBAAQ,MAAM,IAAI,IAAK,MAAM,YAAuB,QAAQ,OAAO,EAAE;AAAA,MACtE;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBACb,SACA,OACA,WACA,SACgC;AAChC,UAAM,UAA0B,EAAE,SAAS,MAAM;AACjD,QAAI,WAAW,OAAO,UAAU,WAAW,QAAQ,EAAE,MAAM;AAE3D,QAAI,KAAK,WAAW;AACnB,YAAM,wBAAwB,oDAA4B,KAAK,OAAO;AACtE,iBAAW,sBAAsB,SAAS,EAAE;AAAA,IAC7C;AAEA,UAAM,UAAU,MAAM,OAAO,QAAQ;AAAA,MACpC;AAAA,MACA,EAAE,MAAM,SAAS;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ;AAAA,IACjB;AAEA,WAAO,CAAC,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBACb,MACA,aACA,MAI+C;AAC/C,UAAM,qBAAqB,MAAM,KAAK,wBAAwB;AAG9D,QAAI,mBAAmB,WAAW,GAAG;AACpC,aAAO,IAAI,yBAAY,EAAE,MAAM,aAAa,KAAK,CAAC;AAAA,IACnD;AAGA,UAAM,SAAS,KAAK,gBAAgB,kBAAkB;AACtD,WAAO,IAAI,mCAAsB,EAAE,QAAQ,MAAM,aAAa,KAAK,CAAC;AAAA,EACrE;AAAA,EAEA,MAAc,0BAAqD;AAClE,UAAM,qBAAuC,CAAC;AAC9C,oDAAuB,KAAK,YAAY,QAAQ,EAAE,YAAY,kBAAkB;AAEhF,UAAM,gBAAgB,oBAAI,IAA4B;AACtD,eAAW,OAAO,oBAAoB;AACrC,oBAAc,IAAI,IAAI,KAAK,GAAG;AAAA,IAC/B;AAEA,WAAO,MAAM,KAAK,cAAc,OAAO,CAAC;AAAA,EACzC;AAAA,EAEQ,gBAAgB,MAA0C;AACjE,UAAM,YAAY,KAAK,OAAO,CAAC,KAAmC,gBAAgB;AACjF,UAAI,YAAY,GAAG,QAAI,uCAAkB,WAAW;AACpD,aAAO;AAAA,IACR,GAAG,CAAC,CAAC;AAEL,WAAO,aAAE,OAAO,SAAS,EAAE,SAAS;AAAA,EACrC;AACD;","names":[]}
@@ -526,7 +526,7 @@ ${import_constants.cssVariables}
526
526
  return {
527
527
  webhookResponse: { data: messages }
528
528
  };
529
- } else if (options?.loadPreviousSession === "notSupported") {
529
+ } else if (!options?.loadPreviousSession || options?.loadPreviousSession === "notSupported") {
530
530
  return {
531
531
  webhookResponse: { data: [] }
532
532
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/ChatTrigger.node.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport { pick } from 'lodash';\nimport { Node, NodeConnectionTypes } from 'n8n-workflow';\nimport type {\n\tIDataObject,\n\tIWebhookFunctions,\n\tIWebhookResponseData,\n\tINodeTypeDescription,\n\tMultiPartFormData,\n\tINodeExecutionData,\n\tIBinaryData,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nimport { cssVariables } from './constants';\nimport { validateAuth } from './GenericFunctions';\nimport { createPage } from './templates';\nimport type { LoadPreviousSessionChatOption } from './types';\n\nconst CHAT_TRIGGER_PATH_IDENTIFIER = 'chat';\nconst allowFileUploadsOption: INodeProperties = {\n\tdisplayName: 'Allow File Uploads',\n\tname: 'allowFileUploads',\n\ttype: 'boolean',\n\tdefault: false,\n\tdescription: 'Whether to allow file uploads in the chat',\n};\nconst allowedFileMimeTypeOption: INodeProperties = {\n\tdisplayName: 'Allowed File Mime Types',\n\tname: 'allowedFilesMimeTypes',\n\ttype: 'string',\n\tdefault: '*',\n\tplaceholder: 'e.g. image/*, text/*, application/pdf',\n\tdescription:\n\t\t'Allowed file types for upload. Comma-separated list of <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\" target=\"_blank\">MIME types</a>.',\n};\n\nexport class ChatTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Chat Trigger',\n\t\tname: 'chatTrigger',\n\t\ticon: 'fa:comments',\n\t\ticonColor: 'black',\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Runs the workflow when an n8n generated webchat is submitted',\n\t\tdefaults: {\n\t\t\tname: 'When chat message received',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['Core Nodes'],\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/core-nodes/n8n-nodes-langchain.chattrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tmaxNodes: 1,\n\t\tinputs: `={{ (() => {\n\t\t\tif (!['hostedChat', 'webhook'].includes($parameter.mode)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tif ($parameter.options?.loadPreviousSession !== 'memory') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Memory',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: '${NodeConnectionTypes.AiMemory}',\n\t\t\t\t\trequired: true,\n\t\t\t\t}\n\t\t\t];\n\t\t })() }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\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: 'httpBasicAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['basicAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: '={{$parameter.options?.[\"responseMode\"] || \"lastNode\" }}',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: '={{ !$parameter.public }}',\n\t\t\t},\n\t\t],\n\t\teventTriggerDescription: 'Waiting for you to submit the chat',\n\t\tactivationMessage: 'You can now make calls to your production chat URL.',\n\t\ttriggerPanel: false,\n\t\tproperties: [\n\t\t\t/**\n\t\t\t * @note If we change this property, also update it in ChatEmbedModal.vue\n\t\t\t */\n\t\t\t{\n\t\t\t\tdisplayName: 'Make Chat Publicly Available',\n\t\t\t\tname: 'public',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether the chat should be publicly available or only accessible through the manual chat interface',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Hosted Chat',\n\t\t\t\t\t\tvalue: 'hostedChat',\n\t\t\t\t\t\tdescription: 'Chat on a page served by n8n',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Embedded Chat',\n\t\t\t\t\t\tvalue: 'webhook',\n\t\t\t\t\t\tdescription: 'Chat through a widget embedded in another page, or by calling a webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'hostedChat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Chat will be live at the URL above once you activate this workflow. Live executions will show up in the ‘executions’ tab',\n\t\t\t\tname: 'hostedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\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:\n\t\t\t\t\t'Follow the instructions <a href=\"https://www.npmjs.com/package/@n8n/chat\" target=\"_blank\">here</a> to embed chat in a webpage (or just call the webhook URL at the top of this section). Chat will be live once you activate this workflow',\n\t\t\t\tname: 'embeddedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['webhook'],\n\t\t\t\t\t\tpublic: [true],\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: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Basic Auth',\n\t\t\t\t\t\tvalue: 'basicAuth',\n\t\t\t\t\t\tdescription: 'Simple username and password (the same one for all users)',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\tname: 'n8n User Auth',\n\t\t\t\t\t\tvalue: 'n8nUserAuth',\n\t\t\t\t\t\tdescription: 'Require user to be logged in with their n8n account',\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',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Initial Message(s)',\n\t\t\t\tname: 'initialMessages',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t\tdefault: 'Hi there! 👋\\nMy name is Nathan. How can I assist you today?',\n\t\t\t\tdescription: 'Default messages shown at the start of the chat, one per line',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [allowFileUploadsOption, allowedFileMimeTypeOption],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t// CORS parameters are only valid for when chat is used in hosted or webhook mode\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Allowed Origins (CORS)',\n\t\t\t\t\t\tname: 'allowedOrigins',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '*',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Comma-separated list of URLs allowed for cross-origin non-preflight requests. Use * (default) to allow all origins.',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat', 'webhook'],\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\t{\n\t\t\t\t\t\t...allowFileUploadsOption,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\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\t{\n\t\t\t\t\t\t...allowedFileMimeTypeOption,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\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\t{\n\t\t\t\t\t\tdisplayName: 'Input Placeholder',\n\t\t\t\t\t\tname: 'inputPlaceholder',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'Type your question..',\n\t\t\t\t\t\tplaceholder: 'e.g. Type your message here',\n\t\t\t\t\t\tdescription: 'Shown as placeholder text in the chat input field',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Load Previous Session',\n\t\t\t\t\t\tname: 'loadPreviousSession',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Off',\n\t\t\t\t\t\t\t\tvalue: 'notSupported',\n\t\t\t\t\t\t\t\tdescription: 'Loading messages of previous session is turned off',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'From Memory',\n\t\t\t\t\t\t\t\tvalue: 'memory',\n\t\t\t\t\t\t\t\tdescription: 'Load session messages from memory',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Manually',\n\t\t\t\t\t\t\t\tvalue: 'manually',\n\t\t\t\t\t\t\t\tdescription: 'Manually return messages of session',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'notSupported',\n\t\t\t\t\t\tdescription: 'If loading messages of a previous session should be enabled',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'When Last Node Finishes',\n\t\t\t\t\t\t\t\tvalue: 'lastNode',\n\t\t\t\t\t\t\t\tdescription: 'Returns data of the last-executed node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: \"Using 'Respond to Webhook' Node\",\n\t\t\t\t\t\t\t\tvalue: 'responseNode',\n\t\t\t\t\t\t\t\tdescription: 'Response defined in that node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Require Button Click to Start Chat',\n\t\t\t\t\t\tname: 'showWelcomeScreen',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescription: 'Whether to show the welcome screen at the start of the chat',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Start Conversation Button Text',\n\t\t\t\t\t\tname: 'getStarted',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tshowWelcomeScreen: [true],\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'New Conversation',\n\t\t\t\t\t\tplaceholder: 'e.g. New Conversation',\n\t\t\t\t\t\tdescription: 'Shown as part of the welcome screen, in the middle of the chat window',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Subtitle',\n\t\t\t\t\t\tname: 'subtitle',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: \"Start a chat. We're here to help you 24/7.\",\n\t\t\t\t\t\tplaceholder: \"e.g. We're here for you\",\n\t\t\t\t\t\tdescription: 'Shown at the top of the chat, under the title',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Title',\n\t\t\t\t\t\tname: 'title',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'Hi there! 👋',\n\t\t\t\t\t\tplaceholder: 'e.g. Welcome',\n\t\t\t\t\t\tdescription: 'Shown at the top of the chat',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Custom Chat Styling',\n\t\t\t\t\t\tname: 'customCss',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\trows: 10,\n\t\t\t\t\t\t\teditor: 'cssEditor',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: `\n${cssVariables}\n\n/* You can override any class styles, too. Right-click inspect in Chat UI to find class to override. */\n.chat-message {\n\tmax-width: 50%;\n}\n`.trim(),\n\t\t\t\t\t\tdescription: 'Override default styling of the public chat interface with CSS',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tprivate async handleFormData(context: IWebhookFunctions) {\n\t\tconst req = context.getRequestObject() as MultiPartFormData.Request;\n\t\tconst options = context.getNodeParameter('options', {}) as IDataObject;\n\t\tconst { data, files } = req.body;\n\n\t\tconst returnItem: INodeExecutionData = {\n\t\t\tjson: data,\n\t\t};\n\n\t\tif (files && Object.keys(files).length) {\n\t\t\treturnItem.json.files = [] as Array<Omit<IBinaryData, 'data'>>;\n\t\t\treturnItem.binary = {};\n\n\t\t\tconst count = 0;\n\t\t\tfor (const fileKey of Object.keys(files)) {\n\t\t\t\tconst processedFiles: MultiPartFormData.File[] = [];\n\t\t\t\tif (Array.isArray(files[fileKey])) {\n\t\t\t\t\tprocessedFiles.push(...files[fileKey]);\n\t\t\t\t} else {\n\t\t\t\t\tprocessedFiles.push(files[fileKey]);\n\t\t\t\t}\n\n\t\t\t\tlet fileIndex = 0;\n\t\t\t\tfor (const file of processedFiles) {\n\t\t\t\t\tlet binaryPropertyName = 'data';\n\n\t\t\t\t\t// Remove the '[]' suffix from the binaryPropertyName if it exists\n\t\t\t\t\tif (binaryPropertyName.endsWith('[]')) {\n\t\t\t\t\t\tbinaryPropertyName = binaryPropertyName.slice(0, -2);\n\t\t\t\t\t}\n\t\t\t\t\tif (options.binaryPropertyName) {\n\t\t\t\t\t\tbinaryPropertyName = `${options.binaryPropertyName.toString()}${count}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst binaryFile = await context.nodeHelpers.copyBinaryFile(\n\t\t\t\t\t\tfile.filepath,\n\t\t\t\t\t\tfile.originalFilename ?? file.newFilename,\n\t\t\t\t\t\tfile.mimetype,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst binaryKey = `${binaryPropertyName}${fileIndex}`;\n\n\t\t\t\t\tconst binaryInfo = {\n\t\t\t\t\t\t...pick(binaryFile, ['fileName', 'fileSize', 'fileType', 'mimeType', 'fileExtension']),\n\t\t\t\t\t\tbinaryKey,\n\t\t\t\t\t};\n\n\t\t\t\t\treturnItem.binary = Object.assign(returnItem.binary ?? {}, {\n\t\t\t\t\t\t[`${binaryKey}`]: binaryFile,\n\t\t\t\t\t});\n\t\t\t\t\treturnItem.json.files = [\n\t\t\t\t\t\t...(returnItem.json.files as Array<Omit<IBinaryData, 'data'>>),\n\t\t\t\t\t\tbinaryInfo,\n\t\t\t\t\t];\n\t\t\t\t\tfileIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn returnItem;\n\t}\n\n\tasync webhook(ctx: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst res = ctx.getResponseObject();\n\n\t\tconst isPublic = ctx.getNodeParameter('public', false) as boolean;\n\t\tconst nodeMode = ctx.getNodeParameter('mode', 'hostedChat') as string;\n\t\tif (!isPublic) {\n\t\t\tres.status(404).end();\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tconst options = ctx.getNodeParameter('options', {}) as {\n\t\t\tgetStarted?: string;\n\t\t\tinputPlaceholder?: string;\n\t\t\tloadPreviousSession?: LoadPreviousSessionChatOption;\n\t\t\tshowWelcomeScreen?: boolean;\n\t\t\tsubtitle?: string;\n\t\t\ttitle?: string;\n\t\t\tallowFileUploads?: boolean;\n\t\t\tallowedFilesMimeTypes?: string;\n\t\t\tcustomCss?: string;\n\t\t};\n\n\t\tconst req = ctx.getRequestObject();\n\t\tconst webhookName = ctx.getWebhookName();\n\t\tconst mode = ctx.getMode() === 'manual' ? 'test' : 'production';\n\t\tconst bodyData = ctx.getBodyData() ?? {};\n\n\t\ttry {\n\t\t\tawait validateAuth(ctx);\n\t\t} catch (error) {\n\t\t\tif (error) {\n\t\t\t\tres.writeHead((error as IDataObject).responseCode as number, {\n\t\t\t\t\t'www-authenticate': 'Basic realm=\"Webhook\"',\n\t\t\t\t});\n\t\t\t\tres.end((error as IDataObject).message as string);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (nodeMode === 'hostedChat') {\n\t\t\t// Show the chat on GET request\n\t\t\tif (webhookName === 'setup') {\n\t\t\t\tconst webhookUrlRaw = ctx.getNodeWebhookUrl('default') as string;\n\t\t\t\tconst webhookUrl =\n\t\t\t\t\tmode === 'test' ? webhookUrlRaw.replace('/webhook', '/webhook-test') : webhookUrlRaw;\n\t\t\t\tconst authentication = ctx.getNodeParameter('authentication') as\n\t\t\t\t\t| 'none'\n\t\t\t\t\t| 'basicAuth'\n\t\t\t\t\t| 'n8nUserAuth';\n\t\t\t\tconst initialMessagesRaw = ctx.getNodeParameter('initialMessages', '') as string;\n\t\t\t\tconst initialMessages = initialMessagesRaw\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.filter((line) => line)\n\t\t\t\t\t.map((line) => line.trim());\n\t\t\t\tconst instanceId = ctx.getInstanceId();\n\n\t\t\t\tconst i18nConfig = pick(options, ['getStarted', 'inputPlaceholder', 'subtitle', 'title']);\n\n\t\t\t\tconst page = createPage({\n\t\t\t\t\ti18n: {\n\t\t\t\t\t\ten: i18nConfig,\n\t\t\t\t\t},\n\t\t\t\t\tshowWelcomeScreen: options.showWelcomeScreen,\n\t\t\t\t\tloadPreviousSession: options.loadPreviousSession,\n\t\t\t\t\tinitialMessages,\n\t\t\t\t\twebhookUrl,\n\t\t\t\t\tmode,\n\t\t\t\t\tinstanceId,\n\t\t\t\t\tauthentication,\n\t\t\t\t\tallowFileUploads: options.allowFileUploads,\n\t\t\t\t\tallowedFilesMimeTypes: options.allowedFilesMimeTypes,\n\t\t\t\t\tcustomCss: options.customCss,\n\t\t\t\t});\n\n\t\t\t\tres.status(200).send(page).end();\n\t\t\t\treturn {\n\t\t\t\t\tnoWebhookResponse: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif (bodyData.action === 'loadPreviousSession') {\n\t\t\tif (options?.loadPreviousSession === 'memory') {\n\t\t\t\tconst memory = (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BaseChatMemory\n\t\t\t\t\t| undefined;\n\t\t\t\tconst messages = ((await memory?.chatHistory.getMessages()) ?? [])\n\t\t\t\t\t.filter((message) => !message?.additional_kwargs?.hideFromUI)\n\t\t\t\t\t.map((message) => message?.toJSON());\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: messages },\n\t\t\t\t};\n\t\t\t} else if (options?.loadPreviousSession === 'notSupported') {\n\t\t\t\t// If messages of a previous session should not be loaded, simply return an empty array\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: [] },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet returnData: INodeExecutionData[];\n\t\tconst webhookResponse: IDataObject = { status: 200 };\n\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\treturn {\n\t\t\t\twebhookResponse,\n\t\t\t\tworkflowData: [returnData],\n\t\t\t};\n\t\t} else {\n\t\t\treturnData = [{ json: bodyData }];\n\t\t}\n\n\t\treturn {\n\t\t\twebhookResponse,\n\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/ChatTrigger.node.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport { pick } from 'lodash';\nimport { Node, NodeConnectionTypes } from 'n8n-workflow';\nimport type {\n\tIDataObject,\n\tIWebhookFunctions,\n\tIWebhookResponseData,\n\tINodeTypeDescription,\n\tMultiPartFormData,\n\tINodeExecutionData,\n\tIBinaryData,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nimport { cssVariables } from './constants';\nimport { validateAuth } from './GenericFunctions';\nimport { createPage } from './templates';\nimport type { LoadPreviousSessionChatOption } from './types';\n\nconst CHAT_TRIGGER_PATH_IDENTIFIER = 'chat';\nconst allowFileUploadsOption: INodeProperties = {\n\tdisplayName: 'Allow File Uploads',\n\tname: 'allowFileUploads',\n\ttype: 'boolean',\n\tdefault: false,\n\tdescription: 'Whether to allow file uploads in the chat',\n};\nconst allowedFileMimeTypeOption: INodeProperties = {\n\tdisplayName: 'Allowed File Mime Types',\n\tname: 'allowedFilesMimeTypes',\n\ttype: 'string',\n\tdefault: '*',\n\tplaceholder: 'e.g. image/*, text/*, application/pdf',\n\tdescription:\n\t\t'Allowed file types for upload. Comma-separated list of <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\" target=\"_blank\">MIME types</a>.',\n};\n\nexport class ChatTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Chat Trigger',\n\t\tname: 'chatTrigger',\n\t\ticon: 'fa:comments',\n\t\ticonColor: 'black',\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Runs the workflow when an n8n generated webchat is submitted',\n\t\tdefaults: {\n\t\t\tname: 'When chat message received',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['Core Nodes'],\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/core-nodes/n8n-nodes-langchain.chattrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tmaxNodes: 1,\n\t\tinputs: `={{ (() => {\n\t\t\tif (!['hostedChat', 'webhook'].includes($parameter.mode)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tif ($parameter.options?.loadPreviousSession !== 'memory') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Memory',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: '${NodeConnectionTypes.AiMemory}',\n\t\t\t\t\trequired: true,\n\t\t\t\t}\n\t\t\t];\n\t\t })() }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\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: 'httpBasicAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['basicAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: '={{$parameter.options?.[\"responseMode\"] || \"lastNode\" }}',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: '={{ !$parameter.public }}',\n\t\t\t},\n\t\t],\n\t\teventTriggerDescription: 'Waiting for you to submit the chat',\n\t\tactivationMessage: 'You can now make calls to your production chat URL.',\n\t\ttriggerPanel: false,\n\t\tproperties: [\n\t\t\t/**\n\t\t\t * @note If we change this property, also update it in ChatEmbedModal.vue\n\t\t\t */\n\t\t\t{\n\t\t\t\tdisplayName: 'Make Chat Publicly Available',\n\t\t\t\tname: 'public',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether the chat should be publicly available or only accessible through the manual chat interface',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Hosted Chat',\n\t\t\t\t\t\tvalue: 'hostedChat',\n\t\t\t\t\t\tdescription: 'Chat on a page served by n8n',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Embedded Chat',\n\t\t\t\t\t\tvalue: 'webhook',\n\t\t\t\t\t\tdescription: 'Chat through a widget embedded in another page, or by calling a webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'hostedChat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Chat will be live at the URL above once you activate this workflow. Live executions will show up in the ‘executions’ tab',\n\t\t\t\tname: 'hostedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\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:\n\t\t\t\t\t'Follow the instructions <a href=\"https://www.npmjs.com/package/@n8n/chat\" target=\"_blank\">here</a> to embed chat in a webpage (or just call the webhook URL at the top of this section). Chat will be live once you activate this workflow',\n\t\t\t\tname: 'embeddedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['webhook'],\n\t\t\t\t\t\tpublic: [true],\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: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Basic Auth',\n\t\t\t\t\t\tvalue: 'basicAuth',\n\t\t\t\t\t\tdescription: 'Simple username and password (the same one for all users)',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\tname: 'n8n User Auth',\n\t\t\t\t\t\tvalue: 'n8nUserAuth',\n\t\t\t\t\t\tdescription: 'Require user to be logged in with their n8n account',\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',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Initial Message(s)',\n\t\t\t\tname: 'initialMessages',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t\tdefault: 'Hi there! 👋\\nMy name is Nathan. How can I assist you today?',\n\t\t\t\tdescription: 'Default messages shown at the start of the chat, one per line',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [allowFileUploadsOption, allowedFileMimeTypeOption],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t// CORS parameters are only valid for when chat is used in hosted or webhook mode\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Allowed Origins (CORS)',\n\t\t\t\t\t\tname: 'allowedOrigins',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '*',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Comma-separated list of URLs allowed for cross-origin non-preflight requests. Use * (default) to allow all origins.',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat', 'webhook'],\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\t{\n\t\t\t\t\t\t...allowFileUploadsOption,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\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\t{\n\t\t\t\t\t\t...allowedFileMimeTypeOption,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\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\t{\n\t\t\t\t\t\tdisplayName: 'Input Placeholder',\n\t\t\t\t\t\tname: 'inputPlaceholder',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'Type your question..',\n\t\t\t\t\t\tplaceholder: 'e.g. Type your message here',\n\t\t\t\t\t\tdescription: 'Shown as placeholder text in the chat input field',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Load Previous Session',\n\t\t\t\t\t\tname: 'loadPreviousSession',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Off',\n\t\t\t\t\t\t\t\tvalue: 'notSupported',\n\t\t\t\t\t\t\t\tdescription: 'Loading messages of previous session is turned off',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'From Memory',\n\t\t\t\t\t\t\t\tvalue: 'memory',\n\t\t\t\t\t\t\t\tdescription: 'Load session messages from memory',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Manually',\n\t\t\t\t\t\t\t\tvalue: 'manually',\n\t\t\t\t\t\t\t\tdescription: 'Manually return messages of session',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'notSupported',\n\t\t\t\t\t\tdescription: 'If loading messages of a previous session should be enabled',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'When Last Node Finishes',\n\t\t\t\t\t\t\t\tvalue: 'lastNode',\n\t\t\t\t\t\t\t\tdescription: 'Returns data of the last-executed node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: \"Using 'Respond to Webhook' Node\",\n\t\t\t\t\t\t\t\tvalue: 'responseNode',\n\t\t\t\t\t\t\t\tdescription: 'Response defined in that node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Require Button Click to Start Chat',\n\t\t\t\t\t\tname: 'showWelcomeScreen',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescription: 'Whether to show the welcome screen at the start of the chat',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Start Conversation Button Text',\n\t\t\t\t\t\tname: 'getStarted',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tshowWelcomeScreen: [true],\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'New Conversation',\n\t\t\t\t\t\tplaceholder: 'e.g. New Conversation',\n\t\t\t\t\t\tdescription: 'Shown as part of the welcome screen, in the middle of the chat window',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Subtitle',\n\t\t\t\t\t\tname: 'subtitle',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: \"Start a chat. We're here to help you 24/7.\",\n\t\t\t\t\t\tplaceholder: \"e.g. We're here for you\",\n\t\t\t\t\t\tdescription: 'Shown at the top of the chat, under the title',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Title',\n\t\t\t\t\t\tname: 'title',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 'Hi there! 👋',\n\t\t\t\t\t\tplaceholder: 'e.g. Welcome',\n\t\t\t\t\t\tdescription: 'Shown at the top of the chat',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Custom Chat Styling',\n\t\t\t\t\t\tname: 'customCss',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\trows: 10,\n\t\t\t\t\t\t\teditor: 'cssEditor',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: `\n${cssVariables}\n\n/* You can override any class styles, too. Right-click inspect in Chat UI to find class to override. */\n.chat-message {\n\tmax-width: 50%;\n}\n`.trim(),\n\t\t\t\t\t\tdescription: 'Override default styling of the public chat interface with CSS',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tprivate async handleFormData(context: IWebhookFunctions) {\n\t\tconst req = context.getRequestObject() as MultiPartFormData.Request;\n\t\tconst options = context.getNodeParameter('options', {}) as IDataObject;\n\t\tconst { data, files } = req.body;\n\n\t\tconst returnItem: INodeExecutionData = {\n\t\t\tjson: data,\n\t\t};\n\n\t\tif (files && Object.keys(files).length) {\n\t\t\treturnItem.json.files = [] as Array<Omit<IBinaryData, 'data'>>;\n\t\t\treturnItem.binary = {};\n\n\t\t\tconst count = 0;\n\t\t\tfor (const fileKey of Object.keys(files)) {\n\t\t\t\tconst processedFiles: MultiPartFormData.File[] = [];\n\t\t\t\tif (Array.isArray(files[fileKey])) {\n\t\t\t\t\tprocessedFiles.push(...files[fileKey]);\n\t\t\t\t} else {\n\t\t\t\t\tprocessedFiles.push(files[fileKey]);\n\t\t\t\t}\n\n\t\t\t\tlet fileIndex = 0;\n\t\t\t\tfor (const file of processedFiles) {\n\t\t\t\t\tlet binaryPropertyName = 'data';\n\n\t\t\t\t\t// Remove the '[]' suffix from the binaryPropertyName if it exists\n\t\t\t\t\tif (binaryPropertyName.endsWith('[]')) {\n\t\t\t\t\t\tbinaryPropertyName = binaryPropertyName.slice(0, -2);\n\t\t\t\t\t}\n\t\t\t\t\tif (options.binaryPropertyName) {\n\t\t\t\t\t\tbinaryPropertyName = `${options.binaryPropertyName.toString()}${count}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst binaryFile = await context.nodeHelpers.copyBinaryFile(\n\t\t\t\t\t\tfile.filepath,\n\t\t\t\t\t\tfile.originalFilename ?? file.newFilename,\n\t\t\t\t\t\tfile.mimetype,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst binaryKey = `${binaryPropertyName}${fileIndex}`;\n\n\t\t\t\t\tconst binaryInfo = {\n\t\t\t\t\t\t...pick(binaryFile, ['fileName', 'fileSize', 'fileType', 'mimeType', 'fileExtension']),\n\t\t\t\t\t\tbinaryKey,\n\t\t\t\t\t};\n\n\t\t\t\t\treturnItem.binary = Object.assign(returnItem.binary ?? {}, {\n\t\t\t\t\t\t[`${binaryKey}`]: binaryFile,\n\t\t\t\t\t});\n\t\t\t\t\treturnItem.json.files = [\n\t\t\t\t\t\t...(returnItem.json.files as Array<Omit<IBinaryData, 'data'>>),\n\t\t\t\t\t\tbinaryInfo,\n\t\t\t\t\t];\n\t\t\t\t\tfileIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn returnItem;\n\t}\n\n\tasync webhook(ctx: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst res = ctx.getResponseObject();\n\n\t\tconst isPublic = ctx.getNodeParameter('public', false) as boolean;\n\t\tconst nodeMode = ctx.getNodeParameter('mode', 'hostedChat') as string;\n\t\tif (!isPublic) {\n\t\t\tres.status(404).end();\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tconst options = ctx.getNodeParameter('options', {}) as {\n\t\t\tgetStarted?: string;\n\t\t\tinputPlaceholder?: string;\n\t\t\tloadPreviousSession?: LoadPreviousSessionChatOption;\n\t\t\tshowWelcomeScreen?: boolean;\n\t\t\tsubtitle?: string;\n\t\t\ttitle?: string;\n\t\t\tallowFileUploads?: boolean;\n\t\t\tallowedFilesMimeTypes?: string;\n\t\t\tcustomCss?: string;\n\t\t};\n\n\t\tconst req = ctx.getRequestObject();\n\t\tconst webhookName = ctx.getWebhookName();\n\t\tconst mode = ctx.getMode() === 'manual' ? 'test' : 'production';\n\t\tconst bodyData = ctx.getBodyData() ?? {};\n\n\t\ttry {\n\t\t\tawait validateAuth(ctx);\n\t\t} catch (error) {\n\t\t\tif (error) {\n\t\t\t\tres.writeHead((error as IDataObject).responseCode as number, {\n\t\t\t\t\t'www-authenticate': 'Basic realm=\"Webhook\"',\n\t\t\t\t});\n\t\t\t\tres.end((error as IDataObject).message as string);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (nodeMode === 'hostedChat') {\n\t\t\t// Show the chat on GET request\n\t\t\tif (webhookName === 'setup') {\n\t\t\t\tconst webhookUrlRaw = ctx.getNodeWebhookUrl('default') as string;\n\t\t\t\tconst webhookUrl =\n\t\t\t\t\tmode === 'test' ? webhookUrlRaw.replace('/webhook', '/webhook-test') : webhookUrlRaw;\n\t\t\t\tconst authentication = ctx.getNodeParameter('authentication') as\n\t\t\t\t\t| 'none'\n\t\t\t\t\t| 'basicAuth'\n\t\t\t\t\t| 'n8nUserAuth';\n\t\t\t\tconst initialMessagesRaw = ctx.getNodeParameter('initialMessages', '') as string;\n\t\t\t\tconst initialMessages = initialMessagesRaw\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.filter((line) => line)\n\t\t\t\t\t.map((line) => line.trim());\n\t\t\t\tconst instanceId = ctx.getInstanceId();\n\n\t\t\t\tconst i18nConfig = pick(options, ['getStarted', 'inputPlaceholder', 'subtitle', 'title']);\n\n\t\t\t\tconst page = createPage({\n\t\t\t\t\ti18n: {\n\t\t\t\t\t\ten: i18nConfig,\n\t\t\t\t\t},\n\t\t\t\t\tshowWelcomeScreen: options.showWelcomeScreen,\n\t\t\t\t\tloadPreviousSession: options.loadPreviousSession,\n\t\t\t\t\tinitialMessages,\n\t\t\t\t\twebhookUrl,\n\t\t\t\t\tmode,\n\t\t\t\t\tinstanceId,\n\t\t\t\t\tauthentication,\n\t\t\t\t\tallowFileUploads: options.allowFileUploads,\n\t\t\t\t\tallowedFilesMimeTypes: options.allowedFilesMimeTypes,\n\t\t\t\t\tcustomCss: options.customCss,\n\t\t\t\t});\n\n\t\t\t\tres.status(200).send(page).end();\n\t\t\t\treturn {\n\t\t\t\t\tnoWebhookResponse: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif (bodyData.action === 'loadPreviousSession') {\n\t\t\tif (options?.loadPreviousSession === 'memory') {\n\t\t\t\tconst memory = (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BaseChatMemory\n\t\t\t\t\t| undefined;\n\t\t\t\tconst messages = ((await memory?.chatHistory.getMessages()) ?? [])\n\t\t\t\t\t.filter((message) => !message?.additional_kwargs?.hideFromUI)\n\t\t\t\t\t.map((message) => message?.toJSON());\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: messages },\n\t\t\t\t};\n\t\t\t} else if (!options?.loadPreviousSession || options?.loadPreviousSession === 'notSupported') {\n\t\t\t\t// If messages of a previous session should not be loaded, simply return an empty array\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: [] },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet returnData: INodeExecutionData[];\n\t\tconst webhookResponse: IDataObject = { status: 200 };\n\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\treturn {\n\t\t\t\twebhookResponse,\n\t\t\t\tworkflowData: [returnData],\n\t\t\t};\n\t\t} else {\n\t\t\treturnData = [{ json: bodyData }];\n\t\t}\n\n\t\treturn {\n\t\t\twebhookResponse,\n\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}