@n8n/n8n-nodes-langchain 1.100.1 → 1.101.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 (178) hide show
  1. package/dist/credentials/WeaviateApi.credentials.js +164 -0
  2. package/dist/credentials/WeaviateApi.credentials.js.map +1 -0
  3. package/dist/known/credentials.json +7 -0
  4. package/dist/known/nodes.json +4 -0
  5. package/dist/nodes/agents/Agent/Agent.node.js +5 -2
  6. package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
  7. package/dist/nodes/agents/Agent/V1/AgentV1.node.js +1 -4
  8. package/dist/nodes/agents/Agent/V1/AgentV1.node.js.map +1 -1
  9. package/dist/nodes/agents/Agent/V2/AgentV2.node.js +23 -6
  10. package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -1
  11. package/dist/nodes/agents/Agent/agents/SqlAgent/description.js +0 -1
  12. package/dist/nodes/agents/Agent/agents/SqlAgent/description.js.map +1 -1
  13. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js +29 -1
  14. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js.map +1 -1
  15. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +83 -1
  16. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
  17. package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -1
  18. package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js +0 -1
  19. package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js.map +1 -1
  20. package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js +0 -1
  21. package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js.map +1 -1
  22. package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js +0 -1
  23. package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js.map +1 -1
  24. package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js +0 -1
  25. package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js.map +1 -1
  26. package/dist/nodes/code/Code.node.js.map +1 -1
  27. package/dist/nodes/document_loaders/DocumentBinaryInputLoader/DocumentBinaryInputLoader.node.js +0 -2
  28. package/dist/nodes/document_loaders/DocumentBinaryInputLoader/DocumentBinaryInputLoader.node.js.map +1 -1
  29. package/dist/nodes/document_loaders/DocumentDefaultDataLoader/DocumentDefaultDataLoader.node.js +0 -2
  30. package/dist/nodes/document_loaders/DocumentDefaultDataLoader/DocumentDefaultDataLoader.node.js.map +1 -1
  31. package/dist/nodes/document_loaders/DocumentGithubLoader/DocumentGithubLoader.node.js +0 -2
  32. package/dist/nodes/document_loaders/DocumentGithubLoader/DocumentGithubLoader.node.js.map +1 -1
  33. package/dist/nodes/document_loaders/DocumentJSONInputLoader/DocumentJsonInputLoader.node.js +0 -2
  34. package/dist/nodes/document_loaders/DocumentJSONInputLoader/DocumentJsonInputLoader.node.js.map +1 -1
  35. package/dist/nodes/embeddings/EmbeddingsAwsBedrock/EmbeddingsAwsBedrock.node.js +0 -2
  36. package/dist/nodes/embeddings/EmbeddingsAwsBedrock/EmbeddingsAwsBedrock.node.js.map +1 -1
  37. package/dist/nodes/embeddings/EmbeddingsAzureOpenAi/EmbeddingsAzureOpenAi.node.js +0 -2
  38. package/dist/nodes/embeddings/EmbeddingsAzureOpenAi/EmbeddingsAzureOpenAi.node.js.map +1 -1
  39. package/dist/nodes/embeddings/EmbeddingsCohere/EmbeddingsCohere.node.js +0 -2
  40. package/dist/nodes/embeddings/EmbeddingsCohere/EmbeddingsCohere.node.js.map +1 -1
  41. package/dist/nodes/embeddings/EmbeddingsGoogleGemini/EmbeddingsGoogleGemini.node.js +0 -2
  42. package/dist/nodes/embeddings/EmbeddingsGoogleGemini/EmbeddingsGoogleGemini.node.js.map +1 -1
  43. package/dist/nodes/embeddings/EmbeddingsGoogleVertex/EmbeddingsGoogleVertex.node.js +0 -2
  44. package/dist/nodes/embeddings/EmbeddingsGoogleVertex/EmbeddingsGoogleVertex.node.js.map +1 -1
  45. package/dist/nodes/embeddings/EmbeddingsHuggingFaceInference/EmbeddingsHuggingFaceInference.node.js +0 -2
  46. package/dist/nodes/embeddings/EmbeddingsHuggingFaceInference/EmbeddingsHuggingFaceInference.node.js.map +1 -1
  47. package/dist/nodes/embeddings/EmbeddingsMistralCloud/EmbeddingsMistralCloud.node.js +0 -2
  48. package/dist/nodes/embeddings/EmbeddingsMistralCloud/EmbeddingsMistralCloud.node.js.map +1 -1
  49. package/dist/nodes/embeddings/EmbeddingsOllama/EmbeddingsOllama.node.js +0 -2
  50. package/dist/nodes/embeddings/EmbeddingsOllama/EmbeddingsOllama.node.js.map +1 -1
  51. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js +0 -2
  52. package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js.map +1 -1
  53. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +4 -5
  54. package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
  55. package/dist/nodes/llms/LMChatOllama/LmChatOllama.node.js +0 -3
  56. package/dist/nodes/llms/LMChatOllama/LmChatOllama.node.js.map +1 -1
  57. package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js +6 -6
  58. package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js.map +1 -1
  59. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js +3 -1
  60. package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js.map +1 -1
  61. package/dist/nodes/llms/LMCohere/LmCohere.node.js +0 -3
  62. package/dist/nodes/llms/LMCohere/LmCohere.node.js.map +1 -1
  63. package/dist/nodes/llms/LMOllama/LmOllama.node.js +0 -3
  64. package/dist/nodes/llms/LMOllama/LmOllama.node.js.map +1 -1
  65. package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js +3 -4
  66. package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js.map +1 -1
  67. package/dist/nodes/llms/LMOpenHuggingFaceInference/LmOpenHuggingFaceInference.node.js +0 -3
  68. package/dist/nodes/llms/LMOpenHuggingFaceInference/LmOpenHuggingFaceInference.node.js.map +1 -1
  69. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js +1 -5
  70. package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js.map +1 -1
  71. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js +3 -4
  72. package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js.map +1 -1
  73. package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js +3 -4
  74. package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js.map +1 -1
  75. package/dist/nodes/llms/LmChatGoogleGemini/LmChatGoogleGemini.node.js +0 -3
  76. package/dist/nodes/llms/LmChatGoogleGemini/LmChatGoogleGemini.node.js.map +1 -1
  77. package/dist/nodes/llms/LmChatGoogleVertex/LmChatGoogleVertex.node.js +0 -3
  78. package/dist/nodes/llms/LmChatGoogleVertex/LmChatGoogleVertex.node.js.map +1 -1
  79. package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js +1 -4
  80. package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js.map +1 -1
  81. package/dist/nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.js +0 -3
  82. package/dist/nodes/llms/LmChatMistralCloud/LmChatMistralCloud.node.js.map +1 -1
  83. package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js +3 -3
  84. package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js.map +1 -1
  85. package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js +3 -4
  86. package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js.map +1 -1
  87. package/dist/nodes/llms/N8nLlmTracing.js.map +1 -1
  88. package/dist/nodes/llms/N8nNonEstimatingTracing.js.map +1 -1
  89. package/dist/nodes/llms/n8nDefaultFailedAttemptHandler.js +1 -1
  90. package/dist/nodes/llms/n8nDefaultFailedAttemptHandler.js.map +1 -1
  91. package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js +0 -2
  92. package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js.map +1 -1
  93. package/dist/nodes/memory/MemoryChatRetriever/MemoryChatRetriever.node.js +0 -2
  94. package/dist/nodes/memory/MemoryChatRetriever/MemoryChatRetriever.node.js.map +1 -1
  95. package/dist/nodes/memory/MemoryManager/MemoryManager.node.js +0 -2
  96. package/dist/nodes/memory/MemoryManager/MemoryManager.node.js.map +1 -1
  97. package/dist/nodes/memory/MemoryMotorhead/MemoryMotorhead.node.js +0 -2
  98. package/dist/nodes/memory/MemoryMotorhead/MemoryMotorhead.node.js.map +1 -1
  99. package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js +0 -2
  100. package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js.map +1 -1
  101. package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js +0 -2
  102. package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js.map +1 -1
  103. package/dist/nodes/memory/MemoryXata/MemoryXata.node.js +0 -2
  104. package/dist/nodes/memory/MemoryXata/MemoryXata.node.js.map +1 -1
  105. package/dist/nodes/memory/MemoryZep/MemoryZep.node.js +0 -2
  106. package/dist/nodes/memory/MemoryZep/MemoryZep.node.js.map +1 -1
  107. package/dist/nodes/output_parser/OutputParserAutofixing/OutputParserAutofixing.node.js +0 -2
  108. package/dist/nodes/output_parser/OutputParserAutofixing/OutputParserAutofixing.node.js.map +1 -1
  109. package/dist/nodes/output_parser/OutputParserItemList/OutputParserItemList.node.js +0 -2
  110. package/dist/nodes/output_parser/OutputParserItemList/OutputParserItemList.node.js.map +1 -1
  111. package/dist/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.js +0 -1
  112. package/dist/nodes/output_parser/OutputParserStructured/OutputParserStructured.node.js.map +1 -1
  113. package/dist/nodes/rerankers/RerankerCohere/RerankerCohere.node.js.map +1 -1
  114. package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js +0 -1
  115. package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js.map +1 -1
  116. package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js +0 -1
  117. package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js.map +1 -1
  118. package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js +0 -2
  119. package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js.map +1 -1
  120. package/dist/nodes/retrievers/RetrieverWorkflow/RetrieverWorkflow.node.js.map +1 -1
  121. package/dist/nodes/text_splitters/TextSplitterCharacterTextSplitter/TextSplitterCharacterTextSplitter.node.js +0 -2
  122. package/dist/nodes/text_splitters/TextSplitterCharacterTextSplitter/TextSplitterCharacterTextSplitter.node.js.map +1 -1
  123. package/dist/nodes/text_splitters/TextSplitterRecursiveCharacterTextSplitter/TextSplitterRecursiveCharacterTextSplitter.node.js +0 -2
  124. package/dist/nodes/text_splitters/TextSplitterRecursiveCharacterTextSplitter/TextSplitterRecursiveCharacterTextSplitter.node.js.map +1 -1
  125. package/dist/nodes/text_splitters/TextSplitterTokenSplitter/TextSplitterTokenSplitter.node.js +0 -2
  126. package/dist/nodes/text_splitters/TextSplitterTokenSplitter/TextSplitterTokenSplitter.node.js.map +1 -1
  127. package/dist/nodes/text_splitters/TextSplitterTokenSplitter/TokenTextSplitter.js.map +1 -1
  128. package/dist/nodes/tools/ToolCalculator/ToolCalculator.node.js +0 -2
  129. package/dist/nodes/tools/ToolCalculator/ToolCalculator.node.js.map +1 -1
  130. package/dist/nodes/tools/ToolCode/ToolCode.node.js +0 -2
  131. package/dist/nodes/tools/ToolCode/ToolCode.node.js.map +1 -1
  132. package/dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js +0 -2
  133. package/dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js.map +1 -1
  134. package/dist/nodes/tools/ToolHttpRequest/utils.js.map +1 -1
  135. package/dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js +0 -2
  136. package/dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js.map +1 -1
  137. package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
  138. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +0 -2
  139. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
  140. package/dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js +0 -2
  141. package/dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js.map +1 -1
  142. package/dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js +0 -2
  143. package/dist/nodes/tools/ToolWolframAlpha/ToolWolframAlpha.node.js.map +1 -1
  144. package/dist/nodes/tools/ToolWorkflow/v1/versionDescription.js +0 -2
  145. package/dist/nodes/tools/ToolWorkflow/v1/versionDescription.js.map +1 -1
  146. package/dist/nodes/tools/ToolWorkflow/v2/versionDescription.js.map +1 -1
  147. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +215 -153
  148. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
  149. package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js +1 -1
  150. package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js.map +1 -1
  151. package/dist/nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.js +0 -1
  152. package/dist/nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.js.map +1 -1
  153. package/dist/nodes/vector_store/VectorStoreInMemoryLoad/VectorStoreInMemoryLoad.node.js +0 -1
  154. package/dist/nodes/vector_store/VectorStoreInMemoryLoad/VectorStoreInMemoryLoad.node.js.map +1 -1
  155. package/dist/nodes/vector_store/VectorStorePGVector/VectorStorePGVector.node.js +2 -2
  156. package/dist/nodes/vector_store/VectorStorePGVector/VectorStorePGVector.node.js.map +1 -1
  157. package/dist/nodes/vector_store/VectorStoreQdrant/VectorStoreQdrant.node.js.map +1 -1
  158. package/dist/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.js.map +1 -1
  159. package/dist/nodes/vector_store/VectorStoreWeaviate/VectorStoreWeaviate.node.js +242 -0
  160. package/dist/nodes/vector_store/VectorStoreWeaviate/VectorStoreWeaviate.node.js.map +1 -0
  161. package/dist/nodes/vector_store/VectorStoreWeaviate/Weaviate.utils.js +127 -0
  162. package/dist/nodes/vector_store/VectorStoreWeaviate/Weaviate.utils.js.map +1 -0
  163. package/dist/nodes/vector_store/VectorStoreWeaviate/weaviate.svg +2 -0
  164. package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js +0 -1
  165. package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js.map +1 -1
  166. package/dist/nodes/vector_store/shared/createVectorStoreNode/methods/listSearch.js +15 -2
  167. package/dist/nodes/vector_store/shared/createVectorStoreNode/methods/listSearch.js.map +1 -1
  168. package/dist/nodes/vector_store/shared/descriptions.js +26 -2
  169. package/dist/nodes/vector_store/shared/descriptions.js.map +1 -1
  170. package/dist/nodes/vendors/OpenAi/actions/assistant/message.operation.js +0 -1
  171. package/dist/nodes/vendors/OpenAi/actions/assistant/message.operation.js.map +1 -1
  172. package/dist/nodes/vendors/OpenAi/actions/versionDescription.js.map +1 -1
  173. package/dist/types/credentials.json +1 -0
  174. package/dist/types/nodes.json +4 -3
  175. package/dist/utils/httpProxyAgent.js +20 -6
  176. package/dist/utils/httpProxyAgent.js.map +1 -1
  177. package/dist/utils/logWrapper.js.map +1 -1
  178. package/package.json +21 -15
@@ -69,6 +69,71 @@ function createAgentExecutor(model, tools, prompt, options, outputParser, memory
69
69
  maxIterations: options.maxIterations ?? 10
70
70
  });
71
71
  }
72
+ async function processEventStream(ctx, eventStream, returnIntermediateSteps = false) {
73
+ const agentResult = {
74
+ output: ""
75
+ };
76
+ if (returnIntermediateSteps) {
77
+ agentResult.intermediateSteps = [];
78
+ }
79
+ ctx.sendChunk("begin");
80
+ for await (const event of eventStream) {
81
+ switch (event.event) {
82
+ case "on_chat_model_stream":
83
+ const chunk = event.data?.chunk;
84
+ if (chunk?.content) {
85
+ const chunkContent = chunk.content;
86
+ let chunkText = "";
87
+ if (Array.isArray(chunkContent)) {
88
+ for (const message of chunkContent) {
89
+ chunkText += message?.text;
90
+ }
91
+ } else if (typeof chunkContent === "string") {
92
+ chunkText = chunkContent;
93
+ }
94
+ ctx.sendChunk("item", chunkText);
95
+ agentResult.output += chunkText;
96
+ }
97
+ break;
98
+ case "on_chat_model_end":
99
+ if (returnIntermediateSteps && event.data) {
100
+ const chatModelData = event.data;
101
+ const output = chatModelData.output;
102
+ if (output?.tool_calls && output.tool_calls.length > 0) {
103
+ for (const toolCall of output.tool_calls) {
104
+ agentResult.intermediateSteps.push({
105
+ action: {
106
+ tool: toolCall.name,
107
+ toolInput: toolCall.args,
108
+ log: output.content || `Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,
109
+ messageLog: [output],
110
+ // Include the full LLM response
111
+ toolCallId: toolCall.id,
112
+ type: toolCall.type
113
+ }
114
+ });
115
+ }
116
+ }
117
+ }
118
+ break;
119
+ case "on_tool_end":
120
+ if (returnIntermediateSteps && event.data && agentResult.intermediateSteps.length > 0) {
121
+ const toolData = event.data;
122
+ const matchingStep = agentResult.intermediateSteps.find(
123
+ (step) => !step.observation && step.action.tool === event.name
124
+ );
125
+ if (matchingStep) {
126
+ matchingStep.observation = toolData.output;
127
+ }
128
+ }
129
+ break;
130
+ default:
131
+ break;
132
+ }
133
+ }
134
+ ctx.sendChunk("end");
135
+ return agentResult;
136
+ }
72
137
  async function toolsAgentExecute() {
73
138
  this.logger.debug("Executing Tools Agent V2");
74
139
  const returnData = [];
@@ -90,6 +155,7 @@ async function toolsAgentExecute() {
90
155
  "Please connect a model to the Fallback Model input or disable the fallback option"
91
156
  );
92
157
  }
158
+ const enableStreaming = this.getNodeParameter("options.enableStreaming", 0, true);
93
159
  for (let i = 0; i < items.length; i += batchSize) {
94
160
  const batch = items.slice(i, i + batchSize);
95
161
  const batchPromises = batch.map(async (_item, batchItemIndex) => {
@@ -127,7 +193,23 @@ async function toolsAgentExecute() {
127
193
  formatting_instructions: "IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer."
128
194
  };
129
195
  const executeOptions = { signal: this.getExecutionCancelSignal() };
130
- return await executor.invoke(invokeParams, executeOptions);
196
+ const isStreamingAvailable = this.isStreaming();
197
+ if (enableStreaming && isStreamingAvailable && this.getNode().typeVersion >= 2.1) {
198
+ const chatHistory = await memory?.chatHistory.getMessages();
199
+ const eventStream = executor.streamEvents(
200
+ {
201
+ ...invokeParams,
202
+ chat_history: chatHistory ?? void 0
203
+ },
204
+ {
205
+ version: "v2",
206
+ ...executeOptions
207
+ }
208
+ );
209
+ return await processEventStream(this, eventStream, options.returnIntermediateSteps);
210
+ } else {
211
+ return await executor.invoke(invokeParams, executeOptions);
212
+ }
131
213
  });
132
214
  const batchResults = await Promise.allSettled(batchPromises);
133
215
  const outputParser = await (0, import_N8nOutputParser.getOptionalOutputParser)(this, 0);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V2/execute.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport {\n\tAgentExecutor,\n\ttype AgentRunnableSequence,\n\tcreateToolCallingAgent,\n} from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError, sleep } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\n/**\n * Creates an agent executor with the given configuration\n */\nfunction createAgentExecutor(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\toptions: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools,\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]);\n\n\treturn AgentExecutor.fromAgentAndTools({\n\t\tagent: runnableAgent,\n\t\tmemory,\n\t\ttools,\n\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n}\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing Tools Agent V2');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The \"text\" parameter is empty.');\n\t\t\t}\n\t\t\tconst outputParser = await getOptionalOutputParser(this, itemIndex);\n\t\t\tconst tools = await getTools(this, outputParser);\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\t\t\t// Create executors for primary and fallback models\n\t\t\tconst executor = createAgentExecutor(\n\t\t\t\tmodel,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\toptions,\n\t\t\t\toutputParser,\n\t\t\t\tmemory,\n\t\t\t\tfallbackModel,\n\t\t\t);\n\t\t\t// Invoke with fallback logic\n\t\t\tconst invokeParams = {\n\t\t\t\tinput,\n\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\tformatting_instructions:\n\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t};\n\t\t\tconst executeOptions = { signal: this.getExecutionCancelSignal() };\n\n\t\t\treturn await executor.invoke(invokeParams, executeOptions);\n\t\t});\n\n\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\t\t// This is only used to check if the output parser is connected\n\t\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\t\tconst outputParser = await getOptionalOutputParser(this, 0);\n\t\tbatchResults.forEach((result, index) => {\n\t\t\tconst itemIndex = i + index;\n\t\t\tif (result.status === 'rejected') {\n\t\t\t\tconst error = result.reason as Error;\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst response = result.value;\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t});\n\n\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\tawait sleep(delayBetweenBatches);\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAiC;AACjC,oBAIO;AAGP,kBAAiB;AACjB,0BAAqD;AAErD,yBAAmB;AAEnB,qBAAqC;AACrC,6BAGO;AAEP,oBAQO;AACP,oBAA+B;AAK/B,SAAS,oBACR,OACA,OACA,QACA,SACA,cACA,QACA,eACC;AACD,QAAM,YAAQ,sCAAuB;AAAA,IACpC,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EACjB,CAAC;AAED,MAAI;AACJ,MAAI,eAAe;AAClB,wBAAgB,sCAAuB;AAAA,MACtC,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IACjB,CAAC;AAAA,EACF;AACA,QAAM,gBAAgB,kCAAiB,KAAK;AAAA,IAC3C,gBAAgB,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI;AAAA,QACvD,mCAAoB,cAAc,MAAM;AAAA,IACxC;AAAA,EACD,CAAC;AAED,SAAO,4BAAc,kBAAkB;AAAA,IACtC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,yBAAyB,QAAQ,4BAA4B;AAAA,IAC7D,eAAe,QAAQ,iBAAiB;AAAA,EACzC,CAAC;AACF;AAcA,eAAsB,oBAA4E;AACjG,OAAK,OAAO,MAAM,0BAA0B;AAE5C,QAAM,aAAmC,CAAC;AAC1C,QAAM,QAAQ,KAAK,aAAa;AAChC,QAAM,YAAY,KAAK,iBAAiB,8BAA8B,GAAG,CAAC;AAC1E,QAAM,sBAAsB,KAAK;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,gBAAgB,KAAK,iBAAiB,iBAAiB,GAAG,KAAK;AACrE,QAAM,SAAS,UAAM,iCAAkB,IAAI;AAC3C,QAAM,QAAQ,UAAM,4BAAa,MAAM,CAAC;AACxC,yBAAAA,SAAO,OAAO,gDAAgD;AAC9D,QAAM,gBAAgB,gBAAgB,UAAM,4BAAa,MAAM,CAAC,IAAI;AAEpE,MAAI,iBAAiB,CAAC,eAAe;AACpC,UAAM,IAAI;AAAA,MACT,KAAK,QAAQ;AAAA,MACb;AAAA,IACD;AAAA,EACD;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AACjD,UAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,SAAS;AAC1C,UAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,mBAAmB;AAChE,YAAM,YAAY,IAAI;AAEtB,YAAM,YAAQ,qCAAqB;AAAA,QAClC,KAAK;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,eAAe;AAAA,MAChB,CAAC;AACD,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,gCAAgC;AAAA,MAC9E;AACA,YAAMC,gBAAe,UAAM,gDAAwB,MAAM,SAAS;AAClE,YAAM,QAAQ,UAAM,wBAAS,MAAMA,aAAY;AAC/C,YAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAQ9D,YAAM,WAAW,UAAM,+BAAgB,MAAM,WAAW;AAAA,QACvD,eAAe,QAAQ;AAAA,QACvB,yBAAyB,QAAQ,2BAA2B;AAAA,QAC5D,cAAAA;AAAA,MACD,CAAC;AACD,YAAM,aAA6B,6BAAc,QAAQ;AAGzD,YAAM,WAAW;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAEA,YAAM,eAAe;AAAA,QACpB;AAAA,QACA,gBAAgB,QAAQ,iBAAiB;AAAA,QACzC,yBACC;AAAA,MACF;AACA,YAAM,iBAAiB,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAEjE,aAAO,MAAM,SAAS,OAAO,cAAc,cAAc;AAAA,IAC1D,CAAC;AAED,UAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAG3D,UAAM,eAAe,UAAM,gDAAwB,MAAM,CAAC;AAC1D,iBAAa,QAAQ,CAAC,QAAQ,UAAU;AACvC,YAAM,YAAY,IAAI;AACtB,UAAI,OAAO,WAAW,YAAY;AACjC,cAAM,QAAQ,OAAO;AACrB,YAAI,KAAK,eAAe,GAAG;AAC1B,qBAAW,KAAK;AAAA,YACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,YAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,UAC/B,CAAC;AACD;AAAA,QACD,OAAO;AACN,gBAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,KAAK;AAAA,QACnD;AAAA,MACD;AACA,YAAM,WAAW,OAAO;AAExB,UAAI,UAAU,cAAc;AAC3B,cAAM,mBAAe;AAAA,UACpB,SAAS;AAAA,QACV;AACA,iBAAS,SAAS,cAAc,UAAU;AAAA,MAC3C;AAGA,YAAM,aAAa;AAAA,QAClB,UAAM,YAAAC;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAAA,QACA,YAAY,EAAE,MAAM,UAAU;AAAA,MAC/B;AAEA,iBAAW,KAAK,UAAU;AAAA,IAC3B,CAAC;AAED,QAAI,IAAI,YAAY,MAAM,UAAU,sBAAsB,GAAG;AAC5D,gBAAM,2BAAM,mBAAmB;AAAA,IAChC;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":["assert","outputParser","omit"]}
1
+ {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V2/execute.ts"],"sourcesContent":["import type { StreamEvent } from '@langchain/core/dist/tracers/event_stream';\nimport type { IterableReadableStream } from '@langchain/core/dist/utils/stream';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AIMessageChunk, MessageContentText } from '@langchain/core/messages';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport {\n\tAgentExecutor,\n\ttype AgentRunnableSequence,\n\tcreateToolCallingAgent,\n} from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError, sleep } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\n/**\n * Creates an agent executor with the given configuration\n */\nfunction createAgentExecutor(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\toptions: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools,\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]);\n\n\treturn AgentExecutor.fromAgentAndTools({\n\t\tagent: runnableAgent,\n\t\tmemory,\n\t\ttools,\n\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n}\n\nasync function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\treturnIntermediateSteps: boolean = false,\n): Promise<{ output: string; intermediateSteps?: any[] }> {\n\tconst agentResult: { output: string; intermediateSteps?: any[] } = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tctx.sendChunk('begin');\n\tfor await (const event of eventStream) {\n\t\t// Stream chat model tokens as they come in\n\t\tswitch (event.event) {\n\t\t\tcase 'on_chat_model_stream':\n\t\t\t\tconst chunk = event.data?.chunk as AIMessageChunk;\n\t\t\t\tif (chunk?.content) {\n\t\t\t\t\tconst chunkContent = chunk.content;\n\t\t\t\t\tlet chunkText = '';\n\t\t\t\t\tif (Array.isArray(chunkContent)) {\n\t\t\t\t\t\tfor (const message of chunkContent) {\n\t\t\t\t\t\t\tchunkText += (message as MessageContentText)?.text;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (typeof chunkContent === 'string') {\n\t\t\t\t\t\tchunkText = chunkContent;\n\t\t\t\t\t}\n\t\t\t\t\tctx.sendChunk('item', chunkText);\n\n\t\t\t\t\tagentResult.output += chunkText;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_chat_model_end':\n\t\t\t\t// Capture full LLM response with tool calls for intermediate steps\n\t\t\t\tif (returnIntermediateSteps && event.data) {\n\t\t\t\t\tconst chatModelData = event.data as any;\n\t\t\t\t\tconst output = chatModelData.output;\n\n\t\t\t\t\t// Check if this LLM response contains tool calls\n\t\t\t\t\tif (output?.tool_calls && output.tool_calls.length > 0) {\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\tagentResult.intermediateSteps!.push({\n\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\t\ttype: toolCall.type,\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\tbreak;\n\t\t\tcase 'on_tool_end':\n\t\t\t\t// Capture tool execution results and match with action\n\t\t\t\tif (returnIntermediateSteps && event.data && agentResult.intermediateSteps!.length > 0) {\n\t\t\t\t\tconst toolData = event.data as any;\n\t\t\t\t\t// Find the matching intermediate step for this tool call\n\t\t\t\t\tconst matchingStep = agentResult.intermediateSteps!.find(\n\t\t\t\t\t\t(step) => !step.observation && step.action.tool === event.name,\n\t\t\t\t\t);\n\t\t\t\t\tif (matchingStep) {\n\t\t\t\t\t\tmatchingStep.observation = toolData.output;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end');\n\n\treturn agentResult;\n}\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing Tools Agent V2');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\t// Check if streaming is enabled\n\tconst enableStreaming = this.getNodeParameter('options.enableStreaming', 0, true) as boolean;\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The \"text\" parameter is empty.');\n\t\t\t}\n\t\t\tconst outputParser = await getOptionalOutputParser(this, itemIndex);\n\t\t\tconst tools = await getTools(this, outputParser);\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\t\t\t// Create executors for primary and fallback models\n\t\t\tconst executor = createAgentExecutor(\n\t\t\t\tmodel,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\toptions,\n\t\t\t\toutputParser,\n\t\t\t\tmemory,\n\t\t\t\tfallbackModel,\n\t\t\t);\n\t\t\t// Invoke with fallback logic\n\t\t\tconst invokeParams = {\n\t\t\t\tinput,\n\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\tformatting_instructions:\n\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t};\n\t\t\tconst executeOptions = { signal: this.getExecutionCancelSignal() };\n\n\t\t\t// Check if streaming is actually available\n\t\t\tconst isStreamingAvailable = this.isStreaming();\n\n\t\t\tif (enableStreaming && isStreamingAvailable && this.getNode().typeVersion >= 2.1) {\n\t\t\t\tconst chatHistory = await memory?.chatHistory.getMessages();\n\t\t\t\tconst eventStream = executor.streamEvents(\n\t\t\t\t\t{\n\t\t\t\t\t\t...invokeParams,\n\t\t\t\t\t\tchat_history: chatHistory ?? undefined,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tversion: 'v2',\n\t\t\t\t\t\t...executeOptions,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn await processEventStream(this, eventStream, options.returnIntermediateSteps);\n\t\t\t} else {\n\t\t\t\t// Handle regular execution\n\t\t\t\treturn await executor.invoke(invokeParams, executeOptions);\n\t\t\t}\n\t\t});\n\n\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\t\t// This is only used to check if the output parser is connected\n\t\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\t\tconst outputParser = await getOptionalOutputParser(this, 0);\n\t\tbatchResults.forEach((result, index) => {\n\t\t\tconst itemIndex = i + index;\n\t\t\tif (result.status === 'rejected') {\n\t\t\t\tconst error = result.reason as Error;\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst response = result.value;\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t});\n\n\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\tawait sleep(delayBetweenBatches);\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":"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","names":["assert","outputParser","omit"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ToolsAgent/common.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, type BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport type { AgentAction, AgentFinish } from 'langchain/agents';\nimport type { ToolsAgentAction } from 'langchain/dist/agents/tool_calling/output_parser';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport { DynamicStructuredTool, type Tool } from 'langchain/tools';\nimport { BINARY_ENCODING, jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions } from 'n8n-workflow';\nimport type { ZodObject } from 'zod';\nimport { z } from 'zod';\n\nimport { isChatInstance, getConnectedTools } from '@utils/helpers';\nimport { type N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n/* -----------------------------------------------------------\n Output Parser Helper\n----------------------------------------------------------- */\n/**\n * Retrieve the output parser schema.\n * If the parser does not return a valid schema, default to a schema with a single text field.\n */\nexport function getOutputParserSchema(\n\toutputParser: N8nOutputParser,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ZodObject<any, any, any, any> {\n\tconst schema =\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t(outputParser.getSchema() as ZodObject<any, any, any, any>) ?? z.object({ text: z.string() });\n\treturn schema;\n}\n\n/* -----------------------------------------------------------\n Binary Data Helpers\n----------------------------------------------------------- */\n/**\n * Extracts binary image messages from the input data.\n * When operating in filesystem mode, the binary stream is first converted to a buffer.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @returns A HumanMessage containing the binary image messages.\n */\nexport async function extractBinaryMessages(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n): Promise<HumanMessage> {\n\tconst binaryData = ctx.getInputData()?.[itemIndex]?.binary ?? {};\n\tconst binaryMessages = await Promise.all(\n\t\tObject.values(binaryData)\n\t\t\t.filter((data) => data.mimeType.startsWith('image/'))\n\t\t\t.map(async (data) => {\n\t\t\t\tlet binaryUrlString: string;\n\n\t\t\t\t// In filesystem mode we need to get binary stream by id before converting it to buffer\n\t\t\t\tif (data.id) {\n\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t);\n\t\t\t\t\tbinaryUrlString = `data:${data.mimeType};base64,${Buffer.from(binaryBuffer).toString(\n\t\t\t\t\t\tBINARY_ENCODING,\n\t\t\t\t\t)}`;\n\t\t\t\t} else {\n\t\t\t\t\tbinaryUrlString = data.data.includes('base64')\n\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t: `data:${data.mimeType};base64,${data.data}`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'image_url',\n\t\t\t\t\timage_url: {\n\t\t\t\t\t\turl: binaryUrlString,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t);\n\treturn new HumanMessage({\n\t\tcontent: [...binaryMessages],\n\t});\n}\n\n/* -----------------------------------------------------------\n Agent Output Format Helpers\n----------------------------------------------------------- */\n/**\n * Fixes empty content messages in agent steps.\n *\n * This function is necessary when using RunnableSequence.from in LangChain.\n * If a tool doesn't have any arguments, LangChain returns input: '' (empty string).\n * This can throw an error for some providers (like Anthropic) which expect the input to always be an object.\n * This function replaces empty string inputs with empty objects to prevent such errors.\n *\n * @param steps - The agent steps to fix\n * @returns The fixed agent steps\n */\nexport function fixEmptyContentMessage(\n\tsteps: AgentFinish | ToolsAgentAction[],\n): AgentFinish | ToolsAgentAction[] {\n\tif (!Array.isArray(steps)) return steps;\n\n\tsteps.forEach((step) => {\n\t\tif ('messageLog' in step && step.messageLog !== undefined) {\n\t\t\tif (Array.isArray(step.messageLog)) {\n\t\t\t\tstep.messageLog.forEach((message: BaseMessage) => {\n\t\t\t\t\tif ('content' in message && Array.isArray(message.content)) {\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\t(message.content as Array<{ input?: string | object }>).forEach((content) => {\n\t\t\t\t\t\t\tif (content.input === '') {\n\t\t\t\t\t\t\t\tcontent.input = {};\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}\n\t\t}\n\t});\n\n\treturn steps;\n}\n\n/**\n * Ensures consistent handling of outputs regardless of the model used,\n * providing a unified output format for further processing.\n *\n * This method is necessary to handle different output formats from various language models.\n * Specifically, it checks if the agent step is the final step (contains returnValues) and determines\n * if the output is a simple string (e.g., from OpenAI models) or an array of outputs (e.g., from Anthropic models).\n *\n * Examples:\n * 1. Anthropic model output:\n * ```json\n * {\n * \"output\": [\n * {\n * \"index\": 0,\n * \"type\": \"text\",\n * \"text\": \"The result of the calculation is approximately 1001.8166...\"\n * }\n * ]\n * }\n *```\n * 2. OpenAI model output:\n * ```json\n * {\n * \"output\": \"The result of the calculation is approximately 1001.82...\"\n * }\n * ```\n *\n * @param steps - The agent finish or agent action steps.\n * @returns The modified agent finish steps or the original steps.\n */\nexport function handleAgentFinishOutput(\n\tsteps: AgentFinish | AgentAction[],\n): AgentFinish | AgentAction[] {\n\ttype AgentMultiOutputFinish = AgentFinish & {\n\t\treturnValues: { output: Array<{ text: string; type: string; index: number }> };\n\t};\n\tconst agentFinishSteps = steps as AgentMultiOutputFinish | AgentFinish;\n\n\tif (agentFinishSteps.returnValues) {\n\t\tconst isMultiOutput = Array.isArray(agentFinishSteps.returnValues?.output);\n\t\tif (isMultiOutput) {\n\t\t\t// If all items in the multi-output array are of type 'text', merge them into a single string\n\t\t\tconst multiOutputSteps = agentFinishSteps.returnValues.output as Array<{\n\t\t\t\tindex: number;\n\t\t\t\ttype: string;\n\t\t\t\ttext: string;\n\t\t\t}>;\n\t\t\tconst isTextOnly = multiOutputSteps.every((output) => 'text' in output);\n\t\t\tif (isTextOnly) {\n\t\t\t\tagentFinishSteps.returnValues.output = multiOutputSteps\n\t\t\t\t\t.map((output) => output.text)\n\t\t\t\t\t.join('\\n')\n\t\t\t\t\t.trim();\n\t\t\t}\n\t\t\treturn agentFinishSteps;\n\t\t}\n\t}\n\n\treturn agentFinishSteps;\n}\n\n/**\n * Wraps the parsed output so that it can be stored in memory.\n * If memory is connected, the output is stringified.\n *\n * @param output - The parsed output object\n * @param memory - The connected memory (if any)\n * @returns The formatted output object\n */\nexport function handleParsedStepOutput(\n\toutput: Record<string, unknown>,\n\tmemory?: BaseChatMemory,\n): { returnValues: Record<string, unknown>; log: string } {\n\treturn {\n\t\treturnValues: memory ? { output: JSON.stringify(output) } : output,\n\t\tlog: 'Final response formatted',\n\t};\n}\n\n/**\n * Parses agent steps using the provided output parser.\n * If the agent used the 'format_final_json_response' tool, the output is parsed accordingly.\n *\n * @param steps - The agent finish or action steps\n * @param outputParser - The output parser (if defined)\n * @param memory - The connected memory (if any)\n * @returns The parsed steps with the final output\n */\nexport const getAgentStepsParser =\n\t(outputParser?: N8nOutputParser, memory?: BaseChatMemory) =>\n\tasync (steps: AgentFinish | AgentAction[]): Promise<AgentFinish | AgentAction[]> => {\n\t\t// Check if the steps contain the 'format_final_json_response' tool invocation.\n\t\tif (Array.isArray(steps)) {\n\t\t\tconst responseParserTool = steps.find((step) => step.tool === 'format_final_json_response');\n\t\t\tif (responseParserTool && outputParser) {\n\t\t\t\tconst toolInput = responseParserTool.toolInput;\n\t\t\t\t// Ensure the tool input is a string\n\t\t\t\tconst parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;\n\t\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, if the steps contain a returnValues field, try to parse them manually.\n\t\tif (outputParser && typeof steps === 'object' && (steps as AgentFinish).returnValues) {\n\t\t\tconst finalResponse = (steps as AgentFinish).returnValues;\n\t\t\tlet parserInput: string;\n\n\t\t\tif (finalResponse instanceof Object) {\n\t\t\t\tif ('output' in finalResponse) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// If the output is an object, we will try to parse it as JSON\n\t\t\t\t\t\t// this is because parser expects stringified JSON object like { \"output\": { .... } }\n\t\t\t\t\t\t// so we try to parse the output before wrapping it and then stringify it\n\t\t\t\t\t\tparserInput = JSON.stringify({ output: jsonParse(finalResponse.output) });\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Fallback to the raw output if parsing fails.\n\t\t\t\t\t\tparserInput = finalResponse.output;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the output is not an object, we will stringify it as it is\n\t\t\t\t\tparserInput = JSON.stringify(finalResponse);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparserInput = finalResponse;\n\t\t\t}\n\n\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t}\n\n\t\treturn handleAgentFinishOutput(steps);\n\t};\n\n/* -----------------------------------------------------------\n Agent Setup Helpers\n----------------------------------------------------------- */\n/**\n * Retrieves the language model from the input connection.\n * Throws an error if the model is not a valid chat instance or does not support tools.\n *\n * @param ctx - The execution context\n * @returns The validated chat model\n */\nexport async function getChatModel(\n\tctx: IExecuteFunctions,\n\tindex: number = 0,\n): Promise<BaseChatModel | undefined> {\n\tconst connectedModels = await ctx.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0);\n\n\tlet model;\n\n\tif (Array.isArray(connectedModels) && index !== undefined) {\n\t\tif (connectedModels.length <= index) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// We get the models in reversed order from the workflow so we need to reverse them to match the right index\n\t\tconst reversedModels = [...connectedModels].reverse();\n\t\tmodel = reversedModels[index] as BaseChatModel;\n\t} else {\n\t\tmodel = connectedModels as BaseChatModel;\n\t}\n\n\tif (!isChatInstance(model) || !model.bindTools) {\n\t\tthrow new NodeOperationError(\n\t\t\tctx.getNode(),\n\t\t\t'Tools Agent requires Chat Model which supports Tools calling',\n\t\t);\n\t}\n\treturn model;\n}\n\n/**\n * Retrieves the memory instance from the input connection if it is connected\n *\n * @param ctx - The execution context\n * @returns The connected memory (if any)\n */\nexport async function getOptionalMemory(\n\tctx: IExecuteFunctions,\n): Promise<BaseChatMemory | undefined> {\n\treturn (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t| BaseChatMemory\n\t\t| undefined;\n}\n\n/**\n * Retrieves the connected tools and (if an output parser is defined)\n * appends a structured output parser tool.\n *\n * @param ctx - The execution context\n * @param outputParser - The optional output parser\n * @returns The array of connected tools\n */\nexport async function getTools(\n\tctx: IExecuteFunctions,\n\toutputParser?: N8nOutputParser,\n): Promise<Array<DynamicStructuredTool | Tool>> {\n\tconst tools = (await getConnectedTools(ctx, true, false)) as Array<DynamicStructuredTool | Tool>;\n\n\t// If an output parser is available, create a dynamic tool to validate the final output.\n\tif (outputParser) {\n\t\tconst schema = getOutputParserSchema(outputParser);\n\t\tconst structuredOutputParserTool = new DynamicStructuredTool({\n\t\t\tschema,\n\t\t\tname: 'format_final_json_response',\n\t\t\tdescription:\n\t\t\t\t'Use this tool to format your final response to the user in a structured JSON format. This tool validates your output against a schema to ensure it meets the required format. ONLY use this tool when you have completed all necessary reasoning and are ready to provide your final answer. Do not use this tool for intermediate steps or for asking questions. The output from this tool will be directly returned to the user.',\n\t\t\t// We do not use a function here because we intercept the output with the parser.\n\t\t\tfunc: async () => '',\n\t\t});\n\t\ttools.push(structuredOutputParserTool);\n\t}\n\treturn tools;\n}\n\n/**\n * Prepares the prompt messages for the agent.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @param options - Options containing systemMessage and other parameters\n * @returns The array of prompt messages\n */\nexport async function prepareMessages(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n\toptions: {\n\t\tsystemMessage?: string;\n\t\tpassthroughBinaryImages?: boolean;\n\t\toutputParser?: N8nOutputParser;\n\t},\n): Promise<BaseMessagePromptTemplateLike[]> {\n\tconst useSystemMessage = options.systemMessage ?? ctx.getNode().typeVersion < 1.9;\n\n\tconst messages: BaseMessagePromptTemplateLike[] = [];\n\n\tif (useSystemMessage) {\n\t\tmessages.push([\n\t\t\t'system',\n\t\t\t`{system_message}${options.outputParser ? '\\n\\n{formatting_instructions}' : ''}`,\n\t\t]);\n\t} else if (options.outputParser) {\n\t\tmessages.push(['system', '{formatting_instructions}']);\n\t}\n\n\tmessages.push(['placeholder', '{chat_history}'], ['human', '{input}']);\n\n\t// If there is binary data and the node option permits it, add a binary message\n\tconst hasBinaryData = ctx.getInputData()?.[itemIndex]?.binary !== undefined;\n\tif (hasBinaryData && options.passthroughBinaryImages) {\n\t\tconst binaryMessage = await extractBinaryMessages(ctx, itemIndex);\n\t\tif (binaryMessage.content.length !== 0) {\n\t\t\tmessages.push(binaryMessage);\n\t\t} else {\n\t\t\tctx.logger.debug('Not attaching binary message, since its content was empty');\n\t\t}\n\t}\n\n\t// We add the agent scratchpad last, so that the agent will not run in loops\n\t// by adding binary messages between each interaction\n\tmessages.push(['placeholder', '{agent_scratchpad}']);\n\treturn messages;\n}\n\n/**\n * Creates the chat prompt from messages.\n *\n * @param messages - The messages array\n * @returns The ChatPromptTemplate instance\n */\nexport function preparePrompt(messages: BaseMessagePromptTemplateLike[]): ChatPromptTemplate {\n\treturn ChatPromptTemplate.fromMessages(messages);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA6B;AAE7B,qBAAuE;AAIvE,mBAAiD;AACjD,0BAAoF;AAGpF,iBAAkB;AAElB,qBAAkD;AAS3C,SAAS,sBACf,cAEgC;AAChC,QAAM;AAAA;AAAA,IAEJ,aAAa,UAAU,KAAuC,aAAE,OAAO,EAAE,MAAM,aAAE,OAAO,EAAE,CAAC;AAAA;AAC7F,SAAO;AACR;AAaA,eAAsB,sBACrB,KACA,WACwB;AACxB,QAAM,aAAa,IAAI,aAAa,IAAI,SAAS,GAAG,UAAU,CAAC;AAC/D,QAAM,iBAAiB,MAAM,QAAQ;AAAA,IACpC,OAAO,OAAO,UAAU,EACtB,OAAO,CAAC,SAAS,KAAK,SAAS,WAAW,QAAQ,CAAC,EACnD,IAAI,OAAO,SAAS;AACpB,UAAI;AAGJ,UAAI,KAAK,IAAI;AACZ,cAAM,eAAe,MAAM,IAAI,QAAQ;AAAA,UACtC,MAAM,IAAI,QAAQ,gBAAgB,KAAK,EAAE;AAAA,QAC1C;AACA,0BAAkB,QAAQ,KAAK,QAAQ,WAAW,OAAO,KAAK,YAAY,EAAE;AAAA,UAC3E;AAAA,QACD,CAAC;AAAA,MACF,OAAO;AACN,0BAAkB,KAAK,KAAK,SAAS,QAAQ,IAC1C,KAAK,OACL,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI;AAAA,MAC7C;AAEA,aAAO;AAAA,QACN,MAAM;AAAA,QACN,WAAW;AAAA,UACV,KAAK;AAAA,QACN;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACH;AACA,SAAO,IAAI,6BAAa;AAAA,IACvB,SAAS,CAAC,GAAG,cAAc;AAAA,EAC5B,CAAC;AACF;AAgBO,SAAS,uBACf,OACmC;AACnC,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAElC,QAAM,QAAQ,CAAC,SAAS;AACvB,QAAI,gBAAgB,QAAQ,KAAK,eAAe,QAAW;AAC1D,UAAI,MAAM,QAAQ,KAAK,UAAU,GAAG;AACnC,aAAK,WAAW,QAAQ,CAAC,YAAyB;AACjD,cAAI,aAAa,WAAW,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAE3D,YAAC,QAAQ,QAA+C,QAAQ,CAAC,YAAY;AAC5E,kBAAI,QAAQ,UAAU,IAAI;AACzB,wBAAQ,QAAQ,CAAC;AAAA,cAClB;AAAA,YACD,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAiCO,SAAS,wBACf,OAC8B;AAI9B,QAAM,mBAAmB;AAEzB,MAAI,iBAAiB,cAAc;AAClC,UAAM,gBAAgB,MAAM,QAAQ,iBAAiB,cAAc,MAAM;AACzE,QAAI,eAAe;AAElB,YAAM,mBAAmB,iBAAiB,aAAa;AAKvD,YAAM,aAAa,iBAAiB,MAAM,CAAC,WAAW,UAAU,MAAM;AACtE,UAAI,YAAY;AACf,yBAAiB,aAAa,SAAS,iBACrC,IAAI,CAAC,WAAW,OAAO,IAAI,EAC3B,KAAK,IAAI,EACT,KAAK;AAAA,MACR;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AAUO,SAAS,uBACf,QACA,QACyD;AACzD,SAAO;AAAA,IACN,cAAc,SAAS,EAAE,QAAQ,KAAK,UAAU,MAAM,EAAE,IAAI;AAAA,IAC5D,KAAK;AAAA,EACN;AACD;AAWO,MAAM,sBACZ,CAAC,cAAgC,WACjC,OAAO,UAA6E;AAEnF,MAAI,MAAM,QAAQ,KAAK,GAAG;AACzB,UAAM,qBAAqB,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,4BAA4B;AAC1F,QAAI,sBAAsB,cAAc;AACvC,YAAM,YAAY,mBAAmB;AAErC,YAAM,cAAc,qBAAqB,SAAS,KAAK,UAAU,SAAS,IAAI;AAC9E,YAAM,eAAgB,MAAM,aAAa,MAAM,WAAW;AAC1D,aAAO,uBAAuB,cAAc,MAAM;AAAA,IACnD;AAAA,EACD;AAGA,MAAI,gBAAgB,OAAO,UAAU,YAAa,MAAsB,cAAc;AACrF,UAAM,gBAAiB,MAAsB;AAC7C,QAAI;AAEJ,QAAI,yBAAyB,QAAQ;AACpC,UAAI,YAAY,eAAe;AAC9B,YAAI;AAIH,wBAAc,KAAK,UAAU,EAAE,YAAQ,+BAAU,cAAc,MAAM,EAAE,CAAC;AAAA,QACzE,SAAS,OAAO;AAEf,wBAAc,cAAc;AAAA,QAC7B;AAAA,MACD,OAAO;AAEN,sBAAc,KAAK,UAAU,aAAa;AAAA,MAC3C;AAAA,IACD,OAAO;AACN,oBAAc;AAAA,IACf;AAEA,UAAM,eAAgB,MAAM,aAAa,MAAM,WAAW;AAC1D,WAAO,uBAAuB,cAAc,MAAM;AAAA,EACnD;AAEA,SAAO,wBAAwB,KAAK;AACrC;AAYD,eAAsB,aACrB,KACA,QAAgB,GACqB;AACrC,QAAM,kBAAkB,MAAM,IAAI,uBAAuB,wCAAoB,iBAAiB,CAAC;AAE/F,MAAI;AAEJ,MAAI,MAAM,QAAQ,eAAe,KAAK,UAAU,QAAW;AAC1D,QAAI,gBAAgB,UAAU,OAAO;AACpC,aAAO;AAAA,IACR;AAEA,UAAM,iBAAiB,CAAC,GAAG,eAAe,EAAE,QAAQ;AACpD,YAAQ,eAAe,KAAK;AAAA,EAC7B,OAAO;AACN,YAAQ;AAAA,EACT;AAEA,MAAI,KAAC,+BAAe,KAAK,KAAK,CAAC,MAAM,WAAW;AAC/C,UAAM,IAAI;AAAA,MACT,IAAI,QAAQ;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAQA,eAAsB,kBACrB,KACsC;AACtC,SAAQ,MAAM,IAAI,uBAAuB,wCAAoB,UAAU,CAAC;AAGzE;AAUA,eAAsB,SACrB,KACA,cAC+C;AAC/C,QAAM,QAAS,UAAM,kCAAkB,KAAK,MAAM,KAAK;AAGvD,MAAI,cAAc;AACjB,UAAM,SAAS,sBAAsB,YAAY;AACjD,UAAM,6BAA6B,IAAI,mCAAsB;AAAA,MAC5D;AAAA,MACA,MAAM;AAAA,MACN,aACC;AAAA;AAAA,MAED,MAAM,YAAY;AAAA,IACnB,CAAC;AACD,UAAM,KAAK,0BAA0B;AAAA,EACtC;AACA,SAAO;AACR;AAUA,eAAsB,gBACrB,KACA,WACA,SAK2C;AAC3C,QAAM,mBAAmB,QAAQ,iBAAiB,IAAI,QAAQ,EAAE,cAAc;AAE9E,QAAM,WAA4C,CAAC;AAEnD,MAAI,kBAAkB;AACrB,aAAS,KAAK;AAAA,MACb;AAAA,MACA,mBAAmB,QAAQ,eAAe,kCAAkC,EAAE;AAAA,IAC/E,CAAC;AAAA,EACF,WAAW,QAAQ,cAAc;AAChC,aAAS,KAAK,CAAC,UAAU,2BAA2B,CAAC;AAAA,EACtD;AAEA,WAAS,KAAK,CAAC,eAAe,gBAAgB,GAAG,CAAC,SAAS,SAAS,CAAC;AAGrE,QAAM,gBAAgB,IAAI,aAAa,IAAI,SAAS,GAAG,WAAW;AAClE,MAAI,iBAAiB,QAAQ,yBAAyB;AACrD,UAAM,gBAAgB,MAAM,sBAAsB,KAAK,SAAS;AAChE,QAAI,cAAc,QAAQ,WAAW,GAAG;AACvC,eAAS,KAAK,aAAa;AAAA,IAC5B,OAAO;AACN,UAAI,OAAO,MAAM,2DAA2D;AAAA,IAC7E;AAAA,EACD;AAIA,WAAS,KAAK,CAAC,eAAe,oBAAoB,CAAC;AACnD,SAAO;AACR;AAQO,SAAS,cAAc,UAA+D;AAC5F,SAAO,kCAAmB,aAAa,QAAQ;AAChD;","names":[]}
1
+ {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ToolsAgent/common.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, type BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport type { AgentAction, AgentFinish } from 'langchain/agents';\nimport type { ToolsAgentAction } from 'langchain/dist/agents/tool_calling/output_parser';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport { DynamicStructuredTool, type Tool } from 'langchain/tools';\nimport { BINARY_ENCODING, jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions } from 'n8n-workflow';\nimport type { ZodObject } from 'zod';\nimport { z } from 'zod';\n\nimport { isChatInstance, getConnectedTools } from '@utils/helpers';\nimport { type N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n/* -----------------------------------------------------------\n Output Parser Helper\n----------------------------------------------------------- */\n/**\n * Retrieve the output parser schema.\n * If the parser does not return a valid schema, default to a schema with a single text field.\n */\nexport function getOutputParserSchema(\n\toutputParser: N8nOutputParser,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ZodObject<any, any, any, any> {\n\tconst schema =\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t(outputParser.getSchema() as ZodObject<any, any, any, any>) ?? z.object({ text: z.string() });\n\treturn schema;\n}\n\n/* -----------------------------------------------------------\n Binary Data Helpers\n----------------------------------------------------------- */\n/**\n * Extracts binary image messages from the input data.\n * When operating in filesystem mode, the binary stream is first converted to a buffer.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @returns A HumanMessage containing the binary image messages.\n */\nexport async function extractBinaryMessages(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n): Promise<HumanMessage> {\n\tconst binaryData = ctx.getInputData()?.[itemIndex]?.binary ?? {};\n\tconst binaryMessages = await Promise.all(\n\t\tObject.values(binaryData)\n\t\t\t.filter((data) => data.mimeType.startsWith('image/'))\n\t\t\t.map(async (data) => {\n\t\t\t\tlet binaryUrlString: string;\n\n\t\t\t\t// In filesystem mode we need to get binary stream by id before converting it to buffer\n\t\t\t\tif (data.id) {\n\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t);\n\t\t\t\t\tbinaryUrlString = `data:${data.mimeType};base64,${Buffer.from(binaryBuffer).toString(\n\t\t\t\t\t\tBINARY_ENCODING,\n\t\t\t\t\t)}`;\n\t\t\t\t} else {\n\t\t\t\t\tbinaryUrlString = data.data.includes('base64')\n\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t: `data:${data.mimeType};base64,${data.data}`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'image_url',\n\t\t\t\t\timage_url: {\n\t\t\t\t\t\turl: binaryUrlString,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t);\n\treturn new HumanMessage({\n\t\tcontent: [...binaryMessages],\n\t});\n}\n\n/* -----------------------------------------------------------\n Agent Output Format Helpers\n----------------------------------------------------------- */\n/**\n * Fixes empty content messages in agent steps.\n *\n * This function is necessary when using RunnableSequence.from in LangChain.\n * If a tool doesn't have any arguments, LangChain returns input: '' (empty string).\n * This can throw an error for some providers (like Anthropic) which expect the input to always be an object.\n * This function replaces empty string inputs with empty objects to prevent such errors.\n *\n * @param steps - The agent steps to fix\n * @returns The fixed agent steps\n */\nexport function fixEmptyContentMessage(\n\tsteps: AgentFinish | ToolsAgentAction[],\n): AgentFinish | ToolsAgentAction[] {\n\tif (!Array.isArray(steps)) return steps;\n\n\tsteps.forEach((step) => {\n\t\tif ('messageLog' in step && step.messageLog !== undefined) {\n\t\t\tif (Array.isArray(step.messageLog)) {\n\t\t\t\tstep.messageLog.forEach((message: BaseMessage) => {\n\t\t\t\t\tif ('content' in message && Array.isArray(message.content)) {\n\t\t\t\t\t\t(message.content as Array<{ input?: string | object }>).forEach((content) => {\n\t\t\t\t\t\t\tif (content.input === '') {\n\t\t\t\t\t\t\t\tcontent.input = {};\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}\n\t\t}\n\t});\n\n\treturn steps;\n}\n\n/**\n * Ensures consistent handling of outputs regardless of the model used,\n * providing a unified output format for further processing.\n *\n * This method is necessary to handle different output formats from various language models.\n * Specifically, it checks if the agent step is the final step (contains returnValues) and determines\n * if the output is a simple string (e.g., from OpenAI models) or an array of outputs (e.g., from Anthropic models).\n *\n * Examples:\n * 1. Anthropic model output:\n * ```json\n * {\n * \"output\": [\n * {\n * \"index\": 0,\n * \"type\": \"text\",\n * \"text\": \"The result of the calculation is approximately 1001.8166...\"\n * }\n * ]\n * }\n *```\n * 2. OpenAI model output:\n * ```json\n * {\n * \"output\": \"The result of the calculation is approximately 1001.82...\"\n * }\n * ```\n *\n * @param steps - The agent finish or agent action steps.\n * @returns The modified agent finish steps or the original steps.\n */\nexport function handleAgentFinishOutput(\n\tsteps: AgentFinish | AgentAction[],\n): AgentFinish | AgentAction[] {\n\ttype AgentMultiOutputFinish = AgentFinish & {\n\t\treturnValues: { output: Array<{ text: string; type: string; index: number }> };\n\t};\n\tconst agentFinishSteps = steps as AgentMultiOutputFinish | AgentFinish;\n\n\tif (agentFinishSteps.returnValues) {\n\t\tconst isMultiOutput = Array.isArray(agentFinishSteps.returnValues?.output);\n\t\tif (isMultiOutput) {\n\t\t\t// If all items in the multi-output array are of type 'text', merge them into a single string\n\t\t\tconst multiOutputSteps = agentFinishSteps.returnValues.output as Array<{\n\t\t\t\tindex: number;\n\t\t\t\ttype: string;\n\t\t\t\ttext: string;\n\t\t\t}>;\n\t\t\tconst isTextOnly = multiOutputSteps.every((output) => 'text' in output);\n\t\t\tif (isTextOnly) {\n\t\t\t\tagentFinishSteps.returnValues.output = multiOutputSteps\n\t\t\t\t\t.map((output) => output.text)\n\t\t\t\t\t.join('\\n')\n\t\t\t\t\t.trim();\n\t\t\t}\n\t\t\treturn agentFinishSteps;\n\t\t}\n\t}\n\n\treturn agentFinishSteps;\n}\n\n/**\n * Wraps the parsed output so that it can be stored in memory.\n * If memory is connected, the output is stringified.\n *\n * @param output - The parsed output object\n * @param memory - The connected memory (if any)\n * @returns The formatted output object\n */\nexport function handleParsedStepOutput(\n\toutput: Record<string, unknown>,\n\tmemory?: BaseChatMemory,\n): { returnValues: Record<string, unknown>; log: string } {\n\treturn {\n\t\treturnValues: memory ? { output: JSON.stringify(output) } : output,\n\t\tlog: 'Final response formatted',\n\t};\n}\n\n/**\n * Parses agent steps using the provided output parser.\n * If the agent used the 'format_final_json_response' tool, the output is parsed accordingly.\n *\n * @param steps - The agent finish or action steps\n * @param outputParser - The output parser (if defined)\n * @param memory - The connected memory (if any)\n * @returns The parsed steps with the final output\n */\nexport const getAgentStepsParser =\n\t(outputParser?: N8nOutputParser, memory?: BaseChatMemory) =>\n\tasync (steps: AgentFinish | AgentAction[]): Promise<AgentFinish | AgentAction[]> => {\n\t\t// Check if the steps contain the 'format_final_json_response' tool invocation.\n\t\tif (Array.isArray(steps)) {\n\t\t\tconst responseParserTool = steps.find((step) => step.tool === 'format_final_json_response');\n\t\t\tif (responseParserTool && outputParser) {\n\t\t\t\tconst toolInput = responseParserTool.toolInput;\n\t\t\t\t// Ensure the tool input is a string\n\t\t\t\tconst parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;\n\t\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, if the steps contain a returnValues field, try to parse them manually.\n\t\tif (outputParser && typeof steps === 'object' && (steps as AgentFinish).returnValues) {\n\t\t\tconst finalResponse = (steps as AgentFinish).returnValues;\n\t\t\tlet parserInput: string;\n\n\t\t\tif (finalResponse instanceof Object) {\n\t\t\t\tif ('output' in finalResponse) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// If the output is an object, we will try to parse it as JSON\n\t\t\t\t\t\t// this is because parser expects stringified JSON object like { \"output\": { .... } }\n\t\t\t\t\t\t// so we try to parse the output before wrapping it and then stringify it\n\t\t\t\t\t\tparserInput = JSON.stringify({ output: jsonParse(finalResponse.output) });\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Fallback to the raw output if parsing fails.\n\t\t\t\t\t\tparserInput = finalResponse.output;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the output is not an object, we will stringify it as it is\n\t\t\t\t\tparserInput = JSON.stringify(finalResponse);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparserInput = finalResponse;\n\t\t\t}\n\n\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t}\n\n\t\treturn handleAgentFinishOutput(steps);\n\t};\n\n/* -----------------------------------------------------------\n Agent Setup Helpers\n----------------------------------------------------------- */\n/**\n * Retrieves the language model from the input connection.\n * Throws an error if the model is not a valid chat instance or does not support tools.\n *\n * @param ctx - The execution context\n * @returns The validated chat model\n */\nexport async function getChatModel(\n\tctx: IExecuteFunctions,\n\tindex: number = 0,\n): Promise<BaseChatModel | undefined> {\n\tconst connectedModels = await ctx.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0);\n\n\tlet model;\n\n\tif (Array.isArray(connectedModels) && index !== undefined) {\n\t\tif (connectedModels.length <= index) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// We get the models in reversed order from the workflow so we need to reverse them to match the right index\n\t\tconst reversedModels = [...connectedModels].reverse();\n\t\tmodel = reversedModels[index] as BaseChatModel;\n\t} else {\n\t\tmodel = connectedModels as BaseChatModel;\n\t}\n\n\tif (!isChatInstance(model) || !model.bindTools) {\n\t\tthrow new NodeOperationError(\n\t\t\tctx.getNode(),\n\t\t\t'Tools Agent requires Chat Model which supports Tools calling',\n\t\t);\n\t}\n\treturn model;\n}\n\n/**\n * Retrieves the memory instance from the input connection if it is connected\n *\n * @param ctx - The execution context\n * @returns The connected memory (if any)\n */\nexport async function getOptionalMemory(\n\tctx: IExecuteFunctions,\n): Promise<BaseChatMemory | undefined> {\n\treturn (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t| BaseChatMemory\n\t\t| undefined;\n}\n\n/**\n * Retrieves the connected tools and (if an output parser is defined)\n * appends a structured output parser tool.\n *\n * @param ctx - The execution context\n * @param outputParser - The optional output parser\n * @returns The array of connected tools\n */\nexport async function getTools(\n\tctx: IExecuteFunctions,\n\toutputParser?: N8nOutputParser,\n): Promise<Array<DynamicStructuredTool | Tool>> {\n\tconst tools = (await getConnectedTools(ctx, true, false)) as Array<DynamicStructuredTool | Tool>;\n\n\t// If an output parser is available, create a dynamic tool to validate the final output.\n\tif (outputParser) {\n\t\tconst schema = getOutputParserSchema(outputParser);\n\t\tconst structuredOutputParserTool = new DynamicStructuredTool({\n\t\t\tschema,\n\t\t\tname: 'format_final_json_response',\n\t\t\tdescription:\n\t\t\t\t'Use this tool to format your final response to the user in a structured JSON format. This tool validates your output against a schema to ensure it meets the required format. ONLY use this tool when you have completed all necessary reasoning and are ready to provide your final answer. Do not use this tool for intermediate steps or for asking questions. The output from this tool will be directly returned to the user.',\n\t\t\t// We do not use a function here because we intercept the output with the parser.\n\t\t\tfunc: async () => '',\n\t\t});\n\t\ttools.push(structuredOutputParserTool);\n\t}\n\treturn tools;\n}\n\n/**\n * Prepares the prompt messages for the agent.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @param options - Options containing systemMessage and other parameters\n * @returns The array of prompt messages\n */\nexport async function prepareMessages(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n\toptions: {\n\t\tsystemMessage?: string;\n\t\tpassthroughBinaryImages?: boolean;\n\t\toutputParser?: N8nOutputParser;\n\t},\n): Promise<BaseMessagePromptTemplateLike[]> {\n\tconst useSystemMessage = options.systemMessage ?? ctx.getNode().typeVersion < 1.9;\n\n\tconst messages: BaseMessagePromptTemplateLike[] = [];\n\n\tif (useSystemMessage) {\n\t\tmessages.push([\n\t\t\t'system',\n\t\t\t`{system_message}${options.outputParser ? '\\n\\n{formatting_instructions}' : ''}`,\n\t\t]);\n\t} else if (options.outputParser) {\n\t\tmessages.push(['system', '{formatting_instructions}']);\n\t}\n\n\tmessages.push(['placeholder', '{chat_history}'], ['human', '{input}']);\n\n\t// If there is binary data and the node option permits it, add a binary message\n\tconst hasBinaryData = ctx.getInputData()?.[itemIndex]?.binary !== undefined;\n\tif (hasBinaryData && options.passthroughBinaryImages) {\n\t\tconst binaryMessage = await extractBinaryMessages(ctx, itemIndex);\n\t\tif (binaryMessage.content.length !== 0) {\n\t\t\tmessages.push(binaryMessage);\n\t\t} else {\n\t\t\tctx.logger.debug('Not attaching binary message, since its content was empty');\n\t\t}\n\t}\n\n\t// We add the agent scratchpad last, so that the agent will not run in loops\n\t// by adding binary messages between each interaction\n\tmessages.push(['placeholder', '{agent_scratchpad}']);\n\treturn messages;\n}\n\n/**\n * Creates the chat prompt from messages.\n *\n * @param messages - The messages array\n * @returns The ChatPromptTemplate instance\n */\nexport function preparePrompt(messages: BaseMessagePromptTemplateLike[]): ChatPromptTemplate {\n\treturn ChatPromptTemplate.fromMessages(messages);\n}\n"],"mappings":"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","names":[]}
@@ -209,7 +209,6 @@ class OpenAiAssistant {
209
209
  properties: {
210
210
  name: "={{$responseItem.name}}",
211
211
  value: "={{$responseItem.id}}",
212
- // eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string
213
212
  description: "={{$responseItem.model}}"
214
213
  }
215
214
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/agents/OpenAiAssistant/OpenAiAssistant.node.ts"],"sourcesContent":["import { AgentExecutor } from 'langchain/agents';\nimport type { OpenAIToolType } from 'langchain/dist/experimental/openai_assistant/schema';\nimport { OpenAIAssistantRunnable } from 'langchain/experimental/openai_assistant';\nimport { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { getConnectedTools } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { formatToOpenAIAssistantTool } from './utils';\n\nexport class OpenAiAssistant implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Assistant',\n\t\tname: 'openAiAssistant',\n\t\thidden: true,\n\t\ticon: 'fa:robot',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Utilizes Assistant API from Open AI.',\n\t\tsubtitle: 'Open AI Assistant',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Assistant',\n\t\t\tcolor: '#404040',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Agents', 'Root Nodes'],\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/root-nodes/n8n-nodes-langchain.openaiassistant/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [\n\t\t\t{ type: NodeConnectionTypes.Main },\n\t\t\t{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' },\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\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:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: 'existing',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use New Assistant',\n\t\t\t\t\t\tvalue: 'new',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use Existing Assistant',\n\t\t\t\t\t\tvalue: 'existing',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Instructions',\n\t\t\t\tname: 'instructions',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'How the Assistant and model should behave or respond',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\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 be used to power the assistant. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>. The Retrieval tool requires gpt-3.5-turbo-1106 and gpt-4-1106-preview models.',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\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: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ $responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct') }}\",\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: 'gpt-3.5-turbo-1106',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Assistant',\n\t\t\t\tname: 'assistantId',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['existing'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdescription:\n\t\t\t\t\t'The assistant to use. <a href=\"https://beta.openai.com/docs/assistants/overview\">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\theaders: {\n\t\t\t\t\t\t\t\t\t'OpenAI-Beta': 'assistants=v1',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/assistants',\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.name}}',\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\t// eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.model}}',\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: 'assistant',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'OpenAI Tools',\n\t\t\t\tname: 'nativeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Code Interpreter',\n\t\t\t\t\t\tvalue: 'code_interpreter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Knowledge Retrieval',\n\t\t\t\t\t\tvalue: 'retrieval',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Connect your own custom tools to this node on the canvas',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Upload files for retrieval using the <a href=\"https://platform.openai.com/playground\" target=\"_blank\">OpenAI website<a/>',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tnoticeTheme: 'info',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: { show: { '/nativeTools': ['retrieval'] } },\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 10000,\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],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst nodeVersion = this.getNode().typeVersion;\n\t\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t\tconst assistantId = this.getNodeParameter('assistantId', itemIndex, '') as string;\n\t\t\t\tconst nativeTools = this.getNodeParameter('nativeTools', itemIndex, []) as Array<\n\t\t\t\t\t'code_interpreter' | 'retrieval'\n\t\t\t\t>;\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tbaseURL?: string;\n\t\t\t\t\tmaxRetries: number;\n\t\t\t\t\ttimeout: number;\n\t\t\t\t};\n\n\t\t\t\tif (input === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst client = new OpenAIClient({\n\t\t\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t\tbaseURL: options.baseURL,\n\t\t\t\t});\n\t\t\t\tlet agent;\n\t\t\t\tconst nativeToolsParsed: OpenAIToolType = nativeTools.map((tool) => ({ type: tool }));\n\t\t\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\t\t\tconst newTools = [...transformedConnectedTools, ...nativeToolsParsed];\n\n\t\t\t\t// Existing agent, update tools with currently assigned\n\t\t\t\tif (assistantId) {\n\t\t\t\t\tagent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\t\t\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst name = this.getNodeParameter('name', itemIndex, '') as string;\n\t\t\t\t\tconst instructions = this.getNodeParameter('instructions', itemIndex, '') as string;\n\t\t\t\t\tconst model = this.getNodeParameter('model', itemIndex, 'gpt-3.5-turbo-1106') as string;\n\n\t\t\t\t\tagent = await OpenAIAssistantRunnable.createAssistant({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tinstructions,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t\tasAgent: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\t\t\t\tagent,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\n\t\t\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tcontent: input,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t});\n\n\t\t\t\treturnData.push({ json: response });\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["OpenAIClient"]}
1
+ {"version":3,"sources":["../../../../nodes/agents/OpenAiAssistant/OpenAiAssistant.node.ts"],"sourcesContent":["import { AgentExecutor } from 'langchain/agents';\nimport type { OpenAIToolType } from 'langchain/dist/experimental/openai_assistant/schema';\nimport { OpenAIAssistantRunnable } from 'langchain/experimental/openai_assistant';\nimport { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { getConnectedTools } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { formatToOpenAIAssistantTool } from './utils';\n\nexport class OpenAiAssistant implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Assistant',\n\t\tname: 'openAiAssistant',\n\t\thidden: true,\n\t\ticon: 'fa:robot',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Utilizes Assistant API from Open AI.',\n\t\tsubtitle: 'Open AI Assistant',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Assistant',\n\t\t\tcolor: '#404040',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Agents', 'Root Nodes'],\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/root-nodes/n8n-nodes-langchain.openaiassistant/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [\n\t\t\t{ type: NodeConnectionTypes.Main },\n\t\t\t{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' },\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\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:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: 'existing',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use New Assistant',\n\t\t\t\t\t\tvalue: 'new',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use Existing Assistant',\n\t\t\t\t\t\tvalue: 'existing',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Instructions',\n\t\t\t\tname: 'instructions',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'How the Assistant and model should behave or respond',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\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 be used to power the assistant. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>. The Retrieval tool requires gpt-3.5-turbo-1106 and gpt-4-1106-preview models.',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\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: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ $responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct') }}\",\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: 'gpt-3.5-turbo-1106',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Assistant',\n\t\t\t\tname: 'assistantId',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['existing'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdescription:\n\t\t\t\t\t'The assistant to use. <a href=\"https://beta.openai.com/docs/assistants/overview\">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\theaders: {\n\t\t\t\t\t\t\t\t\t'OpenAI-Beta': 'assistants=v1',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/assistants',\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.name}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.model}}',\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: 'assistant',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'OpenAI Tools',\n\t\t\t\tname: 'nativeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Code Interpreter',\n\t\t\t\t\t\tvalue: 'code_interpreter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Knowledge Retrieval',\n\t\t\t\t\t\tvalue: 'retrieval',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Connect your own custom tools to this node on the canvas',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Upload files for retrieval using the <a href=\"https://platform.openai.com/playground\" target=\"_blank\">OpenAI website<a/>',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tnoticeTheme: 'info',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: { show: { '/nativeTools': ['retrieval'] } },\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 10000,\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],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst nodeVersion = this.getNode().typeVersion;\n\t\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t\tconst assistantId = this.getNodeParameter('assistantId', itemIndex, '') as string;\n\t\t\t\tconst nativeTools = this.getNodeParameter('nativeTools', itemIndex, []) as Array<\n\t\t\t\t\t'code_interpreter' | 'retrieval'\n\t\t\t\t>;\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tbaseURL?: string;\n\t\t\t\t\tmaxRetries: number;\n\t\t\t\t\ttimeout: number;\n\t\t\t\t};\n\n\t\t\t\tif (input === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst client = new OpenAIClient({\n\t\t\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t\tbaseURL: options.baseURL,\n\t\t\t\t});\n\t\t\t\tlet agent;\n\t\t\t\tconst nativeToolsParsed: OpenAIToolType = nativeTools.map((tool) => ({ type: tool }));\n\t\t\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\t\t\tconst newTools = [...transformedConnectedTools, ...nativeToolsParsed];\n\n\t\t\t\t// Existing agent, update tools with currently assigned\n\t\t\t\tif (assistantId) {\n\t\t\t\t\tagent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\t\t\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst name = this.getNodeParameter('name', itemIndex, '') as string;\n\t\t\t\t\tconst instructions = this.getNodeParameter('instructions', itemIndex, '') as string;\n\t\t\t\t\tconst model = this.getNodeParameter('model', itemIndex, 'gpt-3.5-turbo-1106') as string;\n\n\t\t\t\t\tagent = await OpenAIAssistantRunnable.createAssistant({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tinstructions,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t\tasAgent: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\t\t\t\tagent,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\n\t\t\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tcontent: input,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t});\n\n\t\t\t\treturnData.push({ json: response });\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["OpenAIClient"]}
@@ -54,7 +54,6 @@ class ChainRetrievalQa {
54
54
  ]
55
55
  }
56
56
  },
57
- // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
58
57
  inputs: [
59
58
  import_n8n_workflow.NodeConnectionTypes.Main,
60
59
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import { NodeConnectionTypes, parseErrorMetadata, sleep } from 'n8n-workflow';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { INPUT_TEMPLATE_KEY, LEGACY_INPUT_TEMPLATE_KEY, systemPromptOption } from './constants';\nimport { processItem } from './processItem';\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\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/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\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\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\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...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\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\tgetBatchingOptionFields({\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'options.batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.6 && batchSize >= 1) {\n\t\t\t// Run in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = response.reason;\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\tconst answer = output.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Run for each item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await processItem(this, itemIndex);\n\t\t\t\t\tconst answer = response.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import { NodeConnectionTypes, parseErrorMetadata, sleep } from 'n8n-workflow';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { INPUT_TEMPLATE_KEY, LEGACY_INPUT_TEMPLATE_KEY, systemPromptOption } from './constants';\nimport { processItem } from './processItem';\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\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/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\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...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\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\tgetBatchingOptionFields({\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'options.batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.6 && batchSize >= 1) {\n\t\t\t// Run in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = response.reason;\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\tconst answer = output.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Run for each item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await processItem(this, itemIndex);\n\t\t\t\t\tconst answer = response.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -37,7 +37,6 @@ class ChainSummarizationV1 {
37
37
  name: "Summarization Chain",
38
38
  color: "#909298"
39
39
  },
40
- // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
41
40
  inputs: [
42
41
  import_n8n_workflow.NodeConnectionTypes.Main,
43
42
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport type { SummarizationChainParams } from 'langchain/chains';\nimport { loadSummarizationChain } from 'langchain/chains';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeTypeBaseDescription,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { N8nBinaryLoader } from '@utils/N8nBinaryLoader';\nimport { N8nJsonLoader } from '@utils/N8nJsonLoader';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { REFINE_PROMPT_TEMPLATE, DEFAULT_PROMPT_TEMPLATE } from '../prompt';\n\nexport class ChainSummarizationV1 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\tversion: 1,\n\t\t\tdefaults: {\n\t\t\t\tname: 'Summarization Chain',\n\t\t\t\tcolor: '#909298',\n\t\t\t},\n\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\t\tinputs: [\n\t\t\t\tNodeConnectionTypes.Main,\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Model',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Document',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: NodeConnectionTypes.AiDocument,\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\toutputs: [NodeConnectionTypes.Main],\n\t\t\tcredentials: [],\n\t\t\tproperties: [\n\t\t\t\tgetTemplateNoticeField(1951),\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\tname: 'type',\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'The type of summarization to run',\n\t\t\t\t\tdefault: 'map_reduce',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Map Reduce (Recommended)',\n\t\t\t\t\t\t\tvalue: 'map_reduce',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'Summarize each document (or chunk) individually, then summarize those summaries',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Refine',\n\t\t\t\t\t\t\tvalue: 'refine',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'Summarize the first document (or chunk). Then update that summary based on the next document (or chunk), and repeat.',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Stuff',\n\t\t\t\t\t\t\tvalue: 'stuff',\n\t\t\t\t\t\t\tdescription: 'Pass all documents (or chunks) at once. Ideal for small datasets.',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Options',\n\t\t\t\t\tname: 'options',\n\t\t\t\t\ttype: 'collection',\n\t\t\t\t\tdefault: {},\n\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Final Prompt to Combine',\n\t\t\t\t\t\t\tname: 'combineMapPrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\thint: 'The prompt to combine individual summaries',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['map_reduce'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Individual Summary Prompt',\n\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt to summarize an individual document (or chunk)',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['map_reduce'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['stuff'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Subsequent (Refine) Prompt',\n\t\t\t\t\t\t\tname: 'refinePrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['refine'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: REFINE_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt to refine the summary based on the next document (or chunk)',\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Initial Prompt',\n\t\t\t\t\t\t\tname: 'refineQuestionPrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['refine'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt for the first document (or chunk)',\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\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],\n\t\t};\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Vector Store QA Chain');\n\t\tconst type = this.getNodeParameter('type', 0) as 'map_reduce' | 'stuff' | 'refine';\n\n\t\tconst model = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t0,\n\t\t)) as BaseLanguageModel;\n\n\t\tconst documentInput = (await this.getInputConnectionData(NodeConnectionTypes.AiDocument, 0)) as\n\t\t\t| N8nJsonLoader\n\t\t\t| Array<Document<Record<string, unknown>>>;\n\n\t\tconst options = this.getNodeParameter('options', 0, {}) as {\n\t\t\tprompt?: string;\n\t\t\trefineQuestionPrompt?: string;\n\t\t\trefinePrompt?: string;\n\t\t\tcombineMapPrompt?: string;\n\t\t};\n\n\t\tconst chainArgs: SummarizationChainParams = {\n\t\t\ttype,\n\t\t};\n\n\t\t// Map reduce prompt override\n\t\tif (type === 'map_reduce') {\n\t\t\tconst mapReduceArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'map_reduce';\n\t\t\t};\n\t\t\tif (options.combineMapPrompt) {\n\t\t\t\tmapReduceArgs.combineMapPrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.combineMapPrompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (options.prompt) {\n\t\t\t\tmapReduceArgs.combinePrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.prompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Stuff prompt override\n\t\tif (type === 'stuff') {\n\t\t\tconst stuffArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'stuff';\n\t\t\t};\n\t\t\tif (options.prompt) {\n\t\t\t\tstuffArgs.prompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.prompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Refine prompt override\n\t\tif (type === 'refine') {\n\t\t\tconst refineArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'refine';\n\t\t\t};\n\n\t\t\tif (options.refinePrompt) {\n\t\t\t\trefineArgs.refinePrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.refinePrompt,\n\t\t\t\t\tinputVariables: ['existing_answer', 'text'],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (options.refineQuestionPrompt) {\n\t\t\t\trefineArgs.questionPrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.refineQuestionPrompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst chain = loadSummarizationChain(model, chainArgs);\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tlet processedDocuments: Document[];\n\t\t\tif (documentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader) {\n\t\t\t\tprocessedDocuments = await documentInput.processItem(items[itemIndex], itemIndex);\n\t\t\t} else {\n\t\t\t\tprocessedDocuments = documentInput;\n\t\t\t}\n\n\t\t\tconst response = await chain.call({\n\t\t\t\tinput_documents: processedDocuments,\n\t\t\t});\n\n\t\t\treturnData.push({ json: { response } });\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport type { SummarizationChainParams } from 'langchain/chains';\nimport { loadSummarizationChain } from 'langchain/chains';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeTypeBaseDescription,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { N8nBinaryLoader } from '@utils/N8nBinaryLoader';\nimport { N8nJsonLoader } from '@utils/N8nJsonLoader';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { REFINE_PROMPT_TEMPLATE, DEFAULT_PROMPT_TEMPLATE } from '../prompt';\n\nexport class ChainSummarizationV1 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\tversion: 1,\n\t\t\tdefaults: {\n\t\t\t\tname: 'Summarization Chain',\n\t\t\t\tcolor: '#909298',\n\t\t\t},\n\n\t\t\tinputs: [\n\t\t\t\tNodeConnectionTypes.Main,\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Model',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Document',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: NodeConnectionTypes.AiDocument,\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\toutputs: [NodeConnectionTypes.Main],\n\t\t\tcredentials: [],\n\t\t\tproperties: [\n\t\t\t\tgetTemplateNoticeField(1951),\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\tname: 'type',\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'The type of summarization to run',\n\t\t\t\t\tdefault: 'map_reduce',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Map Reduce (Recommended)',\n\t\t\t\t\t\t\tvalue: 'map_reduce',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'Summarize each document (or chunk) individually, then summarize those summaries',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Refine',\n\t\t\t\t\t\t\tvalue: 'refine',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'Summarize the first document (or chunk). Then update that summary based on the next document (or chunk), and repeat.',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Stuff',\n\t\t\t\t\t\t\tvalue: 'stuff',\n\t\t\t\t\t\t\tdescription: 'Pass all documents (or chunks) at once. Ideal for small datasets.',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Options',\n\t\t\t\t\tname: 'options',\n\t\t\t\t\ttype: 'collection',\n\t\t\t\t\tdefault: {},\n\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Final Prompt to Combine',\n\t\t\t\t\t\t\tname: 'combineMapPrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\thint: 'The prompt to combine individual summaries',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['map_reduce'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Individual Summary Prompt',\n\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt to summarize an individual document (or chunk)',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['map_reduce'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['stuff'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Subsequent (Refine) Prompt',\n\t\t\t\t\t\t\tname: 'refinePrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['refine'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: REFINE_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt to refine the summary based on the next document (or chunk)',\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Initial Prompt',\n\t\t\t\t\t\t\tname: 'refineQuestionPrompt',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/type': ['refine'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\thint: 'The prompt for the first document (or chunk)',\n\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\trows: 6,\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],\n\t\t};\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Vector Store QA Chain');\n\t\tconst type = this.getNodeParameter('type', 0) as 'map_reduce' | 'stuff' | 'refine';\n\n\t\tconst model = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t0,\n\t\t)) as BaseLanguageModel;\n\n\t\tconst documentInput = (await this.getInputConnectionData(NodeConnectionTypes.AiDocument, 0)) as\n\t\t\t| N8nJsonLoader\n\t\t\t| Array<Document<Record<string, unknown>>>;\n\n\t\tconst options = this.getNodeParameter('options', 0, {}) as {\n\t\t\tprompt?: string;\n\t\t\trefineQuestionPrompt?: string;\n\t\t\trefinePrompt?: string;\n\t\t\tcombineMapPrompt?: string;\n\t\t};\n\n\t\tconst chainArgs: SummarizationChainParams = {\n\t\t\ttype,\n\t\t};\n\n\t\t// Map reduce prompt override\n\t\tif (type === 'map_reduce') {\n\t\t\tconst mapReduceArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'map_reduce';\n\t\t\t};\n\t\t\tif (options.combineMapPrompt) {\n\t\t\t\tmapReduceArgs.combineMapPrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.combineMapPrompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (options.prompt) {\n\t\t\t\tmapReduceArgs.combinePrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.prompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Stuff prompt override\n\t\tif (type === 'stuff') {\n\t\t\tconst stuffArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'stuff';\n\t\t\t};\n\t\t\tif (options.prompt) {\n\t\t\t\tstuffArgs.prompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.prompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Refine prompt override\n\t\tif (type === 'refine') {\n\t\t\tconst refineArgs = chainArgs as SummarizationChainParams & {\n\t\t\t\ttype: 'refine';\n\t\t\t};\n\n\t\t\tif (options.refinePrompt) {\n\t\t\t\trefineArgs.refinePrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.refinePrompt,\n\t\t\t\t\tinputVariables: ['existing_answer', 'text'],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (options.refineQuestionPrompt) {\n\t\t\t\trefineArgs.questionPrompt = new PromptTemplate({\n\t\t\t\t\ttemplate: options.refineQuestionPrompt,\n\t\t\t\t\tinputVariables: ['text'],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst chain = loadSummarizationChain(model, chainArgs);\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tlet processedDocuments: Document[];\n\t\t\tif (documentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader) {\n\t\t\t\tprocessedDocuments = await documentInput.processItem(items[itemIndex], itemIndex);\n\t\t\t} else {\n\t\t\t\tprocessedDocuments = documentInput;\n\t\t\t}\n\n\t\t\tconst response = await chain.call({\n\t\t\t\tinput_documents: processedDocuments,\n\t\t\t});\n\n\t\t\treturnData.push({ json: { response } });\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -66,7 +66,6 @@ class ChainSummarizationV2 {
66
66
  name: "Summarization Chain",
67
67
  color: "#909298"
68
68
  },
69
- // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
70
69
  inputs: `={{ ((parameter) => { ${getInputs.toString()}; return getInputs(parameter) })($parameter) }}`,
71
70
  outputs: [import_n8n_workflow.NodeConnectionTypes.Main],
72
71
  credentials: [],