@n8n/n8n-nodes-langchain 1.121.1 → 1.122.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 (137) hide show
  1. package/dist/nodes/Guardrails/Guardrails.node.js +29 -40
  2. package/dist/nodes/Guardrails/Guardrails.node.js.map +1 -1
  3. package/dist/nodes/Guardrails/actions/execute.js +68 -0
  4. package/dist/nodes/Guardrails/actions/execute.js.map +1 -0
  5. package/dist/nodes/Guardrails/actions/process.js +10 -7
  6. package/dist/nodes/Guardrails/actions/process.js.map +1 -1
  7. package/dist/nodes/Guardrails/description.js +326 -365
  8. package/dist/nodes/Guardrails/description.js.map +1 -1
  9. package/dist/nodes/Guardrails/helpers/configureNodeInputs.js +37 -3
  10. package/dist/nodes/Guardrails/helpers/configureNodeInputs.js.map +1 -1
  11. package/dist/nodes/Guardrails/helpers/model.js.map +1 -1
  12. package/dist/nodes/Guardrails/v1/GuardrailsV1.node.js +59 -0
  13. package/dist/nodes/Guardrails/v1/GuardrailsV1.node.js.map +1 -0
  14. package/dist/nodes/Guardrails/v2/GuardrailsV2.node.js +59 -0
  15. package/dist/nodes/Guardrails/v2/GuardrailsV2.node.js.map +1 -0
  16. package/dist/nodes/ToolExecutor/ToolExecutor.node.js.map +1 -1
  17. package/dist/nodes/agents/Agent/agents/ConversationalAgent/execute.js +1 -1
  18. package/dist/nodes/agents/Agent/agents/ConversationalAgent/execute.js.map +1 -1
  19. package/dist/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.js +3 -85
  20. package/dist/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.js.map +1 -1
  21. package/dist/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.js +1 -1
  22. package/dist/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.js.map +1 -1
  23. package/dist/nodes/agents/Agent/agents/ReActAgent/execute.js +1 -1
  24. package/dist/nodes/agents/Agent/agents/ReActAgent/execute.js.map +1 -1
  25. package/dist/nodes/agents/Agent/agents/SqlAgent/execute.js +2 -2
  26. package/dist/nodes/agents/Agent/agents/SqlAgent/execute.js.map +1 -1
  27. package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js +1 -1
  28. package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js.map +1 -1
  29. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +1 -1
  30. package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
  31. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/buildExecutionContext.js.map +1 -1
  32. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.js +1 -1
  33. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.js.map +1 -1
  34. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.js.map +1 -1
  35. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/finalizeResult.js.map +1 -1
  36. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/prepareItemContext.js.map +1 -1
  37. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js +8 -16
  38. package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js.map +1 -1
  39. package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js +1 -1
  40. package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -1
  41. package/dist/nodes/agents/Agent/agents/utils.js.map +1 -1
  42. package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js +2 -2
  43. package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js.map +1 -1
  44. package/dist/nodes/chains/ChainRetrievalQA/processItem.js +2 -2
  45. package/dist/nodes/chains/ChainRetrievalQA/processItem.js.map +1 -1
  46. package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js +1 -1
  47. package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js.map +1 -1
  48. package/dist/nodes/chains/ChainSummarization/V2/processItem.js +1 -1
  49. package/dist/nodes/chains/ChainSummarization/V2/processItem.js.map +1 -1
  50. package/dist/nodes/chains/ChainSummarization/helpers.js.map +1 -1
  51. package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js +1 -1
  52. package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js.map +1 -1
  53. package/dist/nodes/chains/InformationExtractor/processItem.js.map +1 -1
  54. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +1 -1
  55. package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
  56. package/dist/nodes/chains/TextClassifier/TextClassifier.node.js +1 -1
  57. package/dist/nodes/chains/TextClassifier/TextClassifier.node.js.map +1 -1
  58. package/dist/nodes/chains/TextClassifier/processItem.js.map +1 -1
  59. package/dist/nodes/code/Code.node.js +66 -2
  60. package/dist/nodes/code/Code.node.js.map +1 -1
  61. package/dist/nodes/llms/LMOllama/LmOllama.node.js +1 -1
  62. package/dist/nodes/llms/LMOllama/LmOllama.node.js.map +1 -1
  63. package/dist/nodes/mcp/McpClientTool/utils.js +1 -1
  64. package/dist/nodes/mcp/McpClientTool/utils.js.map +1 -1
  65. package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js +1 -1
  66. package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js.map +1 -1
  67. package/dist/nodes/memory/MemoryMongoDbChat/MemoryMongoDbChat.node.js +1 -1
  68. package/dist/nodes/memory/MemoryMongoDbChat/MemoryMongoDbChat.node.js.map +1 -1
  69. package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js +1 -1
  70. package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js.map +1 -1
  71. package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js +1 -1
  72. package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js.map +1 -1
  73. package/dist/nodes/memory/MemoryXata/MemoryXata.node.js +1 -1
  74. package/dist/nodes/memory/MemoryXata/MemoryXata.node.js.map +1 -1
  75. package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js +2 -2
  76. package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js.map +1 -1
  77. package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js +1 -1
  78. package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js.map +1 -1
  79. package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js +1 -1
  80. package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js.map +1 -1
  81. package/dist/nodes/tools/ToolThink/ToolThink.node.js +1 -1
  82. package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
  83. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +2 -2
  84. package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
  85. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +5 -21
  86. package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
  87. package/dist/nodes/trigger/ChatTrigger/Chat.node.js +2 -2
  88. package/dist/nodes/trigger/ChatTrigger/Chat.node.js.map +1 -1
  89. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +1 -1
  90. package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
  91. package/dist/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.js +65 -17
  92. package/dist/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.js.map +1 -1
  93. package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js.map +1 -1
  94. package/dist/nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.js.map +1 -1
  95. package/dist/nodes/vector_store/VectorStoreQdrant/qdrant.svg +23 -19
  96. package/dist/nodes/vector_store/shared/MemoryManager/MemoryCalculator.js.map +1 -1
  97. package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js +1 -1
  98. package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js.map +1 -1
  99. package/dist/nodes/vector_store/shared/MemoryManager/StoreCleanupService.js.map +1 -1
  100. package/dist/nodes/vector_store/shared/MemoryManager/types.js.map +1 -1
  101. package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js +18 -16
  102. package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js.map +1 -1
  103. package/dist/nodes/vendors/GoogleGemini/actions/image/edit.operation.js +6 -1
  104. package/dist/nodes/vendors/GoogleGemini/actions/image/edit.operation.js.map +1 -1
  105. package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js +1 -1
  106. package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js.map +1 -1
  107. package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js +23 -8
  108. package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js.map +1 -1
  109. package/dist/nodes/vendors/OpenAi/helpers/utils.js.map +1 -1
  110. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js +2 -2
  111. package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js.map +1 -1
  112. package/dist/types/nodes.json +7 -6
  113. package/dist/utils/N8nBinaryLoader.js +2 -2
  114. package/dist/utils/N8nBinaryLoader.js.map +1 -1
  115. package/dist/utils/N8nJsonLoader.js +2 -2
  116. package/dist/utils/N8nJsonLoader.js.map +1 -1
  117. package/dist/utils/N8nTool.js +1 -1
  118. package/dist/utils/N8nTool.js.map +1 -1
  119. package/dist/utils/agent-execution/buildSteps.js +12 -8
  120. package/dist/utils/agent-execution/buildSteps.js.map +1 -1
  121. package/dist/utils/agent-execution/createEngineRequests.js +19 -1
  122. package/dist/utils/agent-execution/createEngineRequests.js.map +1 -1
  123. package/dist/utils/agent-execution/index.js +4 -4
  124. package/dist/utils/agent-execution/index.js.map +1 -1
  125. package/dist/utils/agent-execution/memoryManagement.js +15 -14
  126. package/dist/utils/agent-execution/memoryManagement.js.map +1 -1
  127. package/dist/utils/agent-execution/processEventStream.js +1 -47
  128. package/dist/utils/agent-execution/processEventStream.js.map +1 -1
  129. package/dist/utils/agent-execution/types.js.map +1 -1
  130. package/dist/utils/fromAIToolFactory.js +61 -0
  131. package/dist/utils/fromAIToolFactory.js.map +1 -0
  132. package/dist/utils/helpers.js +1 -1
  133. package/dist/utils/helpers.js.map +1 -1
  134. package/dist/utils/logWrapper.js.map +1 -1
  135. package/dist/utils/output_parsers/N8nStructuredOutputParser.js +1 -1
  136. package/dist/utils/output_parsers/N8nStructuredOutputParser.js.map +1 -1
  137. package/package.json +31 -30
@@ -26,8 +26,8 @@ var import_docx = require("@langchain/community/document_loaders/fs/docx");
26
26
  var import_epub = require("@langchain/community/document_loaders/fs/epub");
27
27
  var import_pdf = require("@langchain/community/document_loaders/fs/pdf");
28
28
  var import_fs = require("fs");
29
- var import_json = require("langchain/document_loaders/fs/json");
30
- var import_text = require("langchain/document_loaders/fs/text");
29
+ var import_json = require("@langchain/classic/document_loaders/fs/json");
30
+ var import_text = require("@langchain/classic/document_loaders/fs/text");
31
31
  var import_n8n_workflow = require("n8n-workflow");
32
32
  var import_promises = require("stream/promises");
33
33
  var import_tmp_promise = require("tmp-promise");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../utils/N8nBinaryLoader.ts"],"sourcesContent":["import { CSVLoader } from '@langchain/community/document_loaders/fs/csv';\nimport { DocxLoader } from '@langchain/community/document_loaders/fs/docx';\nimport { EPubLoader } from '@langchain/community/document_loaders/fs/epub';\nimport { PDFLoader } from '@langchain/community/document_loaders/fs/pdf';\nimport type { Document } from '@langchain/core/documents';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { createWriteStream } from 'fs';\nimport { JSONLoader } from 'langchain/document_loaders/fs/json';\nimport { TextLoader } from 'langchain/document_loaders/fs/text';\nimport type {\n\tIBinaryData,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tISupplyDataFunctions,\n} from 'n8n-workflow';\nimport { NodeOperationError, BINARY_ENCODING } from 'n8n-workflow';\nimport { pipeline } from 'stream/promises';\nimport { file as tmpFile, type DirectoryResult } from 'tmp-promise';\n\nimport { getMetadataFiltersValues } from './helpers';\n\nconst SUPPORTED_MIME_TYPES = {\n\tauto: ['*/*'],\n\tpdfLoader: ['application/pdf'],\n\tcsvLoader: ['text/csv'],\n\tepubLoader: ['application/epub+zip'],\n\tdocxLoader: ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\n\ttextLoader: ['text/plain', 'text/mdx', 'text/md', 'text/markdown'],\n\tjsonLoader: ['application/json'],\n};\n\nexport class N8nBinaryLoader {\n\tconstructor(\n\t\tprivate context: IExecuteFunctions | ISupplyDataFunctions,\n\t\tprivate optionsPrefix = '',\n\t\tprivate binaryDataKey = '',\n\t\tprivate textSplitter?: TextSplitter,\n\t) {}\n\n\tasync processAll(items?: INodeExecutionData[]): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\n\t\tif (!items) return [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst processedDocuments = await this.processItem(items[itemIndex], itemIndex);\n\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tprivate async validateMimeType(\n\t\tmimeType: string,\n\t\tselectedLoader: keyof typeof SUPPORTED_MIME_TYPES,\n\t): Promise<void> {\n\t\t// Check if loader matches the mime-type of the data\n\t\tif (selectedLoader !== 'auto' && !SUPPORTED_MIME_TYPES[selectedLoader].includes(mimeType)) {\n\t\t\tconst neededLoader = Object.keys(SUPPORTED_MIME_TYPES).find((loader) =>\n\t\t\t\tSUPPORTED_MIME_TYPES[loader as keyof typeof SUPPORTED_MIME_TYPES].includes(mimeType),\n\t\t\t);\n\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.context.getNode(),\n\t\t\t\t`Mime type doesn't match selected loader. Please select under \"Loader Type\": ${neededLoader}`,\n\t\t\t);\n\t\t}\n\n\t\tif (!Object.values(SUPPORTED_MIME_TYPES).flat().includes(mimeType)) {\n\t\t\tthrow new NodeOperationError(this.context.getNode(), `Unsupported mime type: ${mimeType}`);\n\t\t}\n\n\t\tif (\n\t\t\t!SUPPORTED_MIME_TYPES[selectedLoader].includes(mimeType) &&\n\t\t\tselectedLoader !== 'textLoader' &&\n\t\t\tselectedLoader !== 'auto'\n\t\t) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.context.getNode(),\n\t\t\t\t`Unsupported mime type: ${mimeType} for selected loader: ${selectedLoader}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getFilePathOrBlob(\n\t\tbinaryData: IBinaryData,\n\t\tmimeType: string,\n\t): Promise<string | Blob> {\n\t\tif (binaryData.id) {\n\t\t\tconst binaryBuffer = await this.context.helpers.binaryToBuffer(\n\t\t\t\tawait this.context.helpers.getBinaryStream(binaryData.id),\n\t\t\t);\n\t\t\treturn new Blob([binaryBuffer as BlobPart], {\n\t\t\t\ttype: mimeType,\n\t\t\t});\n\t\t} else {\n\t\t\treturn new Blob([Buffer.from(binaryData.data, BINARY_ENCODING)], {\n\t\t\t\ttype: mimeType,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async getLoader(\n\t\tmimeType: string,\n\t\tfilePathOrBlob: string | Blob,\n\t\titemIndex: number,\n\t): Promise<PDFLoader | CSVLoader | EPubLoader | DocxLoader | TextLoader | JSONLoader> {\n\t\tswitch (mimeType) {\n\t\t\tcase 'application/pdf':\n\t\t\t\tconst splitPages = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}splitPages`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\tfalse,\n\t\t\t\t) as boolean;\n\t\t\t\treturn new PDFLoader(filePathOrBlob, { splitPages });\n\t\t\tcase 'text/csv':\n\t\t\t\tconst column = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}column`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\tnull,\n\t\t\t\t) as string;\n\t\t\t\tconst separator = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}separator`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\t',',\n\t\t\t\t) as string;\n\t\t\t\treturn new CSVLoader(filePathOrBlob, { column: column ?? undefined, separator });\n\t\t\tcase 'application/epub+zip':\n\t\t\t\t// EPubLoader currently does not accept Blobs https://github.com/langchain-ai/langchainjs/issues/1623\n\t\t\t\tlet filePath: string;\n\t\t\t\tif (filePathOrBlob instanceof Blob) {\n\t\t\t\t\tconst tmpFileData = await tmpFile({ prefix: 'epub-loader-' });\n\t\t\t\t\tconst bufferData = await filePathOrBlob.arrayBuffer();\n\t\t\t\t\tawait pipeline([new Uint8Array(bufferData)], createWriteStream(tmpFileData.path));\n\t\t\t\t\treturn new EPubLoader(tmpFileData.path);\n\t\t\t\t} else {\n\t\t\t\t\tfilePath = filePathOrBlob;\n\t\t\t\t}\n\t\t\t\treturn new EPubLoader(filePath);\n\t\t\tcase 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n\t\t\t\treturn new DocxLoader(filePathOrBlob);\n\t\t\tcase 'text/plain':\n\t\t\t\treturn new TextLoader(filePathOrBlob);\n\t\t\tcase 'application/json':\n\t\t\t\tconst pointers = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}pointers`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\t'',\n\t\t\t\t) as string;\n\t\t\t\tconst pointersArray = pointers.split(',').map((pointer) => pointer.trim());\n\t\t\t\treturn new JSONLoader(filePathOrBlob, pointersArray);\n\t\t\tdefault:\n\t\t\t\treturn new TextLoader(filePathOrBlob);\n\t\t}\n\t}\n\n\tprivate async loadDocuments(\n\t\tloader: PDFLoader | CSVLoader | EPubLoader | DocxLoader | TextLoader | JSONLoader,\n\t): Promise<Document[]> {\n\t\treturn this.textSplitter\n\t\t\t? await this.textSplitter.splitDocuments(await loader.load())\n\t\t\t: await loader.load();\n\t}\n\n\tprivate async cleanupTmpFileIfNeeded(\n\t\tcleanupTmpFile: DirectoryResult['cleanup'] | undefined,\n\t): Promise<void> {\n\t\tif (cleanupTmpFile) {\n\t\t\tawait cleanupTmpFile();\n\t\t}\n\t}\n\n\tasync processItem(item: INodeExecutionData, itemIndex: number): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\t\tconst binaryMode = this.context.getNodeParameter('binaryMode', itemIndex, 'allInputData');\n\t\tif (binaryMode === 'allInputData') {\n\t\t\tconst binaryData = this.context.getInputData();\n\n\t\t\tfor (const data of binaryData) {\n\t\t\t\tif (data.binary) {\n\t\t\t\t\tconst binaryDataKeys = Object.keys(data.binary);\n\n\t\t\t\t\tfor (const fileKey of binaryDataKeys) {\n\t\t\t\t\t\tconst processedDocuments = await this.processItemByKey(item, itemIndex, fileKey);\n\t\t\t\t\t\tdocs.push(...processedDocuments);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst processedDocuments = await this.processItemByKey(item, itemIndex, this.binaryDataKey);\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tasync processItemByKey(\n\t\titem: INodeExecutionData,\n\t\titemIndex: number,\n\t\tbinaryKey: string,\n\t): Promise<Document[]> {\n\t\tconst selectedLoader: keyof typeof SUPPORTED_MIME_TYPES = this.context.getNodeParameter(\n\t\t\t'loader',\n\t\t\titemIndex,\n\t\t\t'auto',\n\t\t) as keyof typeof SUPPORTED_MIME_TYPES;\n\n\t\tconst docs: Document[] = [];\n\t\tconst metadata = getMetadataFiltersValues(this.context, itemIndex);\n\n\t\tif (!item) return [];\n\n\t\tconst binaryData = this.context.helpers.assertBinaryData(itemIndex, binaryKey);\n\t\tconst { mimeType } = binaryData;\n\n\t\tawait this.validateMimeType(mimeType, selectedLoader);\n\n\t\tconst filePathOrBlob = await this.getFilePathOrBlob(binaryData, mimeType);\n\t\tconst cleanupTmpFile: DirectoryResult['cleanup'] | undefined = undefined;\n\t\tconst loader = await this.getLoader(mimeType, filePathOrBlob, itemIndex);\n\t\tconst loadedDoc = await this.loadDocuments(loader);\n\n\t\tdocs.push(...loadedDoc);\n\n\t\tif (metadata) {\n\t\t\tdocs.forEach((document) => {\n\t\t\t\tdocument.metadata = {\n\t\t\t\t\t...document.metadata,\n\t\t\t\t\t...metadata,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tawait this.cleanupTmpFileIfNeeded(cleanupTmpFile);\n\n\t\treturn docs;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0B;AAC1B,kBAA2B;AAC3B,kBAA2B;AAC3B,iBAA0B;AAG1B,gBAAkC;AAClC,kBAA2B;AAC3B,kBAA2B;AAO3B,0BAAoD;AACpD,sBAAyB;AACzB,yBAAsD;AAEtD,qBAAyC;AAEzC,MAAM,uBAAuB;AAAA,EAC5B,MAAM,CAAC,KAAK;AAAA,EACZ,WAAW,CAAC,iBAAiB;AAAA,EAC7B,WAAW,CAAC,UAAU;AAAA,EACtB,YAAY,CAAC,sBAAsB;AAAA,EACnC,YAAY,CAAC,yEAAyE;AAAA,EACtF,YAAY,CAAC,cAAc,YAAY,WAAW,eAAe;AAAA,EACjE,YAAY,CAAC,kBAAkB;AAChC;AAEO,MAAM,gBAAgB;AAAA,EAC5B,YACS,SACA,gBAAgB,IAChB,gBAAgB,IAChB,cACP;AAJO;AACA;AACA;AACA;AAAA,EACN;AAAA,EAEH,MAAM,WAAW,OAAmD;AACnE,UAAM,OAAmB,CAAC;AAE1B,QAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,aAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,YAAM,qBAAqB,MAAM,KAAK,YAAY,MAAM,SAAS,GAAG,SAAS;AAE7E,WAAK,KAAK,GAAG,kBAAkB;AAAA,IAChC;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAc,iBACb,UACA,gBACgB;AAEhB,QAAI,mBAAmB,UAAU,CAAC,qBAAqB,cAAc,EAAE,SAAS,QAAQ,GAAG;AAC1F,YAAM,eAAe,OAAO,KAAK,oBAAoB,EAAE;AAAA,QAAK,CAAC,WAC5D,qBAAqB,MAA2C,EAAE,SAAS,QAAQ;AAAA,MACpF;AAEA,YAAM,IAAI;AAAA,QACT,KAAK,QAAQ,QAAQ;AAAA,QACrB,+EAA+E,YAAY;AAAA,MAC5F;AAAA,IACD;AAEA,QAAI,CAAC,OAAO,OAAO,oBAAoB,EAAE,KAAK,EAAE,SAAS,QAAQ,GAAG;AACnE,YAAM,IAAI,uCAAmB,KAAK,QAAQ,QAAQ,GAAG,0BAA0B,QAAQ,EAAE;AAAA,IAC1F;AAEA,QACC,CAAC,qBAAqB,cAAc,EAAE,SAAS,QAAQ,KACvD,mBAAmB,gBACnB,mBAAmB,QAClB;AACD,YAAM,IAAI;AAAA,QACT,KAAK,QAAQ,QAAQ;AAAA,QACrB,0BAA0B,QAAQ,yBAAyB,cAAc;AAAA,MAC1E;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,kBACb,YACA,UACyB;AACzB,QAAI,WAAW,IAAI;AAClB,YAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ;AAAA,QAC/C,MAAM,KAAK,QAAQ,QAAQ,gBAAgB,WAAW,EAAE;AAAA,MACzD;AACA,aAAO,IAAI,KAAK,CAAC,YAAwB,GAAG;AAAA,QAC3C,MAAM;AAAA,MACP,CAAC;AAAA,IACF,OAAO;AACN,aAAO,IAAI,KAAK,CAAC,OAAO,KAAK,WAAW,MAAM,mCAAe,CAAC,GAAG;AAAA,QAChE,MAAM;AAAA,MACP,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,MAAc,UACb,UACA,gBACA,WACqF;AACrF,YAAQ,UAAU;AAAA,MACjB,KAAK;AACJ,cAAM,aAAa,KAAK,QAAQ;AAAA,UAC/B,GAAG,KAAK,aAAa;AAAA,UACrB;AAAA,UACA;AAAA,QACD;AACA,eAAO,IAAI,qBAAU,gBAAgB,EAAE,WAAW,CAAC;AAAA,MACpD,KAAK;AACJ,cAAM,SAAS,KAAK,QAAQ;AAAA,UAC3B,GAAG,KAAK,aAAa;AAAA,UACrB;AAAA,UACA;AAAA,QACD;AACA,cAAM,YAAY,KAAK,QAAQ;AAAA,UAC9B,GAAG,KAAK,aAAa;AAAA,UACrB;AAAA,UACA;AAAA,QACD;AACA,eAAO,IAAI,qBAAU,gBAAgB,EAAE,QAAQ,UAAU,QAAW,UAAU,CAAC;AAAA,MAChF,KAAK;AAEJ,YAAI;AACJ,YAAI,0BAA0B,MAAM;AACnC,gBAAM,cAAc,UAAM,mBAAAA,MAAQ,EAAE,QAAQ,eAAe,CAAC;AAC5D,gBAAM,aAAa,MAAM,eAAe,YAAY;AACpD,oBAAM,0BAAS,CAAC,IAAI,WAAW,UAAU,CAAC,OAAG,6BAAkB,YAAY,IAAI,CAAC;AAChF,iBAAO,IAAI,uBAAW,YAAY,IAAI;AAAA,QACvC,OAAO;AACN,qBAAW;AAAA,QACZ;AACA,eAAO,IAAI,uBAAW,QAAQ;AAAA,MAC/B,KAAK;AACJ,eAAO,IAAI,uBAAW,cAAc;AAAA,MACrC,KAAK;AACJ,eAAO,IAAI,uBAAW,cAAc;AAAA,MACrC,KAAK;AACJ,cAAM,WAAW,KAAK,QAAQ;AAAA,UAC7B,GAAG,KAAK,aAAa;AAAA,UACrB;AAAA,UACA;AAAA,QACD;AACA,cAAM,gBAAgB,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,YAAY,QAAQ,KAAK,CAAC;AACzE,eAAO,IAAI,uBAAW,gBAAgB,aAAa;AAAA,MACpD;AACC,eAAO,IAAI,uBAAW,cAAc;AAAA,IACtC;AAAA,EACD;AAAA,EAEA,MAAc,cACb,QACsB;AACtB,WAAO,KAAK,eACT,MAAM,KAAK,aAAa,eAAe,MAAM,OAAO,KAAK,CAAC,IAC1D,MAAM,OAAO,KAAK;AAAA,EACtB;AAAA,EAEA,MAAc,uBACb,gBACgB;AAChB,QAAI,gBAAgB;AACnB,YAAM,eAAe;AAAA,IACtB;AAAA,EACD;AAAA,EAEA,MAAM,YAAY,MAA0B,WAAwC;AACnF,UAAM,OAAmB,CAAC;AAC1B,UAAM,aAAa,KAAK,QAAQ,iBAAiB,cAAc,WAAW,cAAc;AACxF,QAAI,eAAe,gBAAgB;AAClC,YAAM,aAAa,KAAK,QAAQ,aAAa;AAE7C,iBAAW,QAAQ,YAAY;AAC9B,YAAI,KAAK,QAAQ;AAChB,gBAAM,iBAAiB,OAAO,KAAK,KAAK,MAAM;AAE9C,qBAAW,WAAW,gBAAgB;AACrC,kBAAM,qBAAqB,MAAM,KAAK,iBAAiB,MAAM,WAAW,OAAO;AAC/E,iBAAK,KAAK,GAAG,kBAAkB;AAAA,UAChC;AAAA,QACD;AAAA,MACD;AAAA,IACD,OAAO;AACN,YAAM,qBAAqB,MAAM,KAAK,iBAAiB,MAAM,WAAW,KAAK,aAAa;AAC1F,WAAK,KAAK,GAAG,kBAAkB;AAAA,IAChC;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,iBACL,MACA,WACA,WACsB;AACtB,UAAM,iBAAoD,KAAK,QAAQ;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,UAAM,OAAmB,CAAC;AAC1B,UAAM,eAAW,yCAAyB,KAAK,SAAS,SAAS;AAEjE,QAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,UAAM,aAAa,KAAK,QAAQ,QAAQ,iBAAiB,WAAW,SAAS;AAC7E,UAAM,EAAE,SAAS,IAAI;AAErB,UAAM,KAAK,iBAAiB,UAAU,cAAc;AAEpD,UAAM,iBAAiB,MAAM,KAAK,kBAAkB,YAAY,QAAQ;AACxE,UAAM,iBAAyD;AAC/D,UAAM,SAAS,MAAM,KAAK,UAAU,UAAU,gBAAgB,SAAS;AACvE,UAAM,YAAY,MAAM,KAAK,cAAc,MAAM;AAEjD,SAAK,KAAK,GAAG,SAAS;AAEtB,QAAI,UAAU;AACb,WAAK,QAAQ,CAAC,aAAa;AAC1B,iBAAS,WAAW;AAAA,UACnB,GAAG,SAAS;AAAA,UACZ,GAAG;AAAA,QACJ;AAAA,MACD,CAAC;AAAA,IACF;AAEA,UAAM,KAAK,uBAAuB,cAAc;AAEhD,WAAO;AAAA,EACR;AACD;","names":["tmpFile"]}
1
+ {"version":3,"sources":["../../utils/N8nBinaryLoader.ts"],"sourcesContent":["import { CSVLoader } from '@langchain/community/document_loaders/fs/csv';\nimport { DocxLoader } from '@langchain/community/document_loaders/fs/docx';\nimport { EPubLoader } from '@langchain/community/document_loaders/fs/epub';\nimport { PDFLoader } from '@langchain/community/document_loaders/fs/pdf';\nimport type { Document } from '@langchain/core/documents';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { createWriteStream } from 'fs';\nimport { JSONLoader } from '@langchain/classic/document_loaders/fs/json';\nimport { TextLoader } from '@langchain/classic/document_loaders/fs/text';\nimport type {\n\tIBinaryData,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tISupplyDataFunctions,\n} from 'n8n-workflow';\nimport { NodeOperationError, BINARY_ENCODING } from 'n8n-workflow';\nimport { pipeline } from 'stream/promises';\nimport { file as tmpFile, type DirectoryResult } from 'tmp-promise';\n\nimport { getMetadataFiltersValues } from './helpers';\n\nconst SUPPORTED_MIME_TYPES = {\n\tauto: ['*/*'],\n\tpdfLoader: ['application/pdf'],\n\tcsvLoader: ['text/csv'],\n\tepubLoader: ['application/epub+zip'],\n\tdocxLoader: ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\n\ttextLoader: ['text/plain', 'text/mdx', 'text/md', 'text/markdown'],\n\tjsonLoader: ['application/json'],\n};\n\nexport class N8nBinaryLoader {\n\tconstructor(\n\t\tprivate context: IExecuteFunctions | ISupplyDataFunctions,\n\t\tprivate optionsPrefix = '',\n\t\tprivate binaryDataKey = '',\n\t\tprivate textSplitter?: TextSplitter,\n\t) {}\n\n\tasync processAll(items?: INodeExecutionData[]): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\n\t\tif (!items) return [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst processedDocuments = await this.processItem(items[itemIndex], itemIndex);\n\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tprivate async validateMimeType(\n\t\tmimeType: string,\n\t\tselectedLoader: keyof typeof SUPPORTED_MIME_TYPES,\n\t): Promise<void> {\n\t\t// Check if loader matches the mime-type of the data\n\t\tif (selectedLoader !== 'auto' && !SUPPORTED_MIME_TYPES[selectedLoader].includes(mimeType)) {\n\t\t\tconst neededLoader = Object.keys(SUPPORTED_MIME_TYPES).find((loader) =>\n\t\t\t\tSUPPORTED_MIME_TYPES[loader as keyof typeof SUPPORTED_MIME_TYPES].includes(mimeType),\n\t\t\t);\n\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.context.getNode(),\n\t\t\t\t`Mime type doesn't match selected loader. Please select under \"Loader Type\": ${neededLoader}`,\n\t\t\t);\n\t\t}\n\n\t\tif (!Object.values(SUPPORTED_MIME_TYPES).flat().includes(mimeType)) {\n\t\t\tthrow new NodeOperationError(this.context.getNode(), `Unsupported mime type: ${mimeType}`);\n\t\t}\n\n\t\tif (\n\t\t\t!SUPPORTED_MIME_TYPES[selectedLoader].includes(mimeType) &&\n\t\t\tselectedLoader !== 'textLoader' &&\n\t\t\tselectedLoader !== 'auto'\n\t\t) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tthis.context.getNode(),\n\t\t\t\t`Unsupported mime type: ${mimeType} for selected loader: ${selectedLoader}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getFilePathOrBlob(\n\t\tbinaryData: IBinaryData,\n\t\tmimeType: string,\n\t): Promise<string | Blob> {\n\t\tif (binaryData.id) {\n\t\t\tconst binaryBuffer = await this.context.helpers.binaryToBuffer(\n\t\t\t\tawait this.context.helpers.getBinaryStream(binaryData.id),\n\t\t\t);\n\t\t\treturn new Blob([binaryBuffer as BlobPart], {\n\t\t\t\ttype: mimeType,\n\t\t\t});\n\t\t} else {\n\t\t\treturn new Blob([Buffer.from(binaryData.data, BINARY_ENCODING)], {\n\t\t\t\ttype: mimeType,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async getLoader(\n\t\tmimeType: string,\n\t\tfilePathOrBlob: string | Blob,\n\t\titemIndex: number,\n\t): Promise<PDFLoader | CSVLoader | EPubLoader | DocxLoader | TextLoader | JSONLoader> {\n\t\tswitch (mimeType) {\n\t\t\tcase 'application/pdf':\n\t\t\t\tconst splitPages = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}splitPages`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\tfalse,\n\t\t\t\t) as boolean;\n\t\t\t\treturn new PDFLoader(filePathOrBlob, { splitPages });\n\t\t\tcase 'text/csv':\n\t\t\t\tconst column = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}column`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\tnull,\n\t\t\t\t) as string;\n\t\t\t\tconst separator = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}separator`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\t',',\n\t\t\t\t) as string;\n\t\t\t\treturn new CSVLoader(filePathOrBlob, { column: column ?? undefined, separator });\n\t\t\tcase 'application/epub+zip':\n\t\t\t\t// EPubLoader currently does not accept Blobs https://github.com/langchain-ai/langchainjs/issues/1623\n\t\t\t\tlet filePath: string;\n\t\t\t\tif (filePathOrBlob instanceof Blob) {\n\t\t\t\t\tconst tmpFileData = await tmpFile({ prefix: 'epub-loader-' });\n\t\t\t\t\tconst bufferData = await filePathOrBlob.arrayBuffer();\n\t\t\t\t\tawait pipeline([new Uint8Array(bufferData)], createWriteStream(tmpFileData.path));\n\t\t\t\t\treturn new EPubLoader(tmpFileData.path);\n\t\t\t\t} else {\n\t\t\t\t\tfilePath = filePathOrBlob;\n\t\t\t\t}\n\t\t\t\treturn new EPubLoader(filePath);\n\t\t\tcase 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n\t\t\t\treturn new DocxLoader(filePathOrBlob);\n\t\t\tcase 'text/plain':\n\t\t\t\treturn new TextLoader(filePathOrBlob);\n\t\t\tcase 'application/json':\n\t\t\t\tconst pointers = this.context.getNodeParameter(\n\t\t\t\t\t`${this.optionsPrefix}pointers`,\n\t\t\t\t\titemIndex,\n\t\t\t\t\t'',\n\t\t\t\t) as string;\n\t\t\t\tconst pointersArray = pointers.split(',').map((pointer) => pointer.trim());\n\t\t\t\treturn new JSONLoader(filePathOrBlob, pointersArray);\n\t\t\tdefault:\n\t\t\t\treturn new TextLoader(filePathOrBlob);\n\t\t}\n\t}\n\n\tprivate async loadDocuments(\n\t\tloader: PDFLoader | CSVLoader | EPubLoader | DocxLoader | TextLoader | JSONLoader,\n\t): Promise<Document[]> {\n\t\treturn this.textSplitter\n\t\t\t? await this.textSplitter.splitDocuments(await loader.load())\n\t\t\t: await loader.load();\n\t}\n\n\tprivate async cleanupTmpFileIfNeeded(\n\t\tcleanupTmpFile: DirectoryResult['cleanup'] | undefined,\n\t): Promise<void> {\n\t\tif (cleanupTmpFile) {\n\t\t\tawait cleanupTmpFile();\n\t\t}\n\t}\n\n\tasync processItem(item: INodeExecutionData, itemIndex: number): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\t\tconst binaryMode = this.context.getNodeParameter('binaryMode', itemIndex, 'allInputData');\n\t\tif (binaryMode === 'allInputData') {\n\t\t\tconst binaryData = this.context.getInputData();\n\n\t\t\tfor (const data of binaryData) {\n\t\t\t\tif (data.binary) {\n\t\t\t\t\tconst binaryDataKeys = Object.keys(data.binary);\n\n\t\t\t\t\tfor (const fileKey of binaryDataKeys) {\n\t\t\t\t\t\tconst processedDocuments = await this.processItemByKey(item, itemIndex, fileKey);\n\t\t\t\t\t\tdocs.push(...processedDocuments);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst processedDocuments = await this.processItemByKey(item, itemIndex, this.binaryDataKey);\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tasync processItemByKey(\n\t\titem: INodeExecutionData,\n\t\titemIndex: number,\n\t\tbinaryKey: string,\n\t): Promise<Document[]> {\n\t\tconst selectedLoader: keyof typeof SUPPORTED_MIME_TYPES = this.context.getNodeParameter(\n\t\t\t'loader',\n\t\t\titemIndex,\n\t\t\t'auto',\n\t\t) as keyof typeof SUPPORTED_MIME_TYPES;\n\n\t\tconst docs: Document[] = [];\n\t\tconst metadata = getMetadataFiltersValues(this.context, itemIndex);\n\n\t\tif (!item) return [];\n\n\t\tconst binaryData = this.context.helpers.assertBinaryData(itemIndex, binaryKey);\n\t\tconst { mimeType } = binaryData;\n\n\t\tawait this.validateMimeType(mimeType, selectedLoader);\n\n\t\tconst filePathOrBlob = await this.getFilePathOrBlob(binaryData, mimeType);\n\t\tconst cleanupTmpFile: DirectoryResult['cleanup'] | undefined = undefined;\n\t\tconst loader = await this.getLoader(mimeType, filePathOrBlob, itemIndex);\n\t\tconst loadedDoc = await this.loadDocuments(loader);\n\n\t\tdocs.push(...loadedDoc);\n\n\t\tif (metadata) {\n\t\t\tdocs.forEach((document) => {\n\t\t\t\tdocument.metadata = {\n\t\t\t\t\t...document.metadata,\n\t\t\t\t\t...metadata,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tawait this.cleanupTmpFileIfNeeded(cleanupTmpFile);\n\n\t\treturn docs;\n\t}\n}\n"],"mappings":"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","names":["tmpFile"]}
@@ -21,8 +21,8 @@ __export(N8nJsonLoader_exports, {
21
21
  N8nJsonLoader: () => N8nJsonLoader
22
22
  });
23
23
  module.exports = __toCommonJS(N8nJsonLoader_exports);
24
- var import_json = require("langchain/document_loaders/fs/json");
25
- var import_text = require("langchain/document_loaders/fs/text");
24
+ var import_json = require("@langchain/classic/document_loaders/fs/json");
25
+ var import_text = require("@langchain/classic/document_loaders/fs/text");
26
26
  var import_n8n_workflow = require("n8n-workflow");
27
27
  var import_helpers = require("./helpers");
28
28
  class N8nJsonLoader {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../utils/N8nJsonLoader.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { JSONLoader } from 'langchain/document_loaders/fs/json';\nimport { TextLoader } from 'langchain/document_loaders/fs/text';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype ISupplyDataFunctions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { getMetadataFiltersValues } from './helpers';\n\nexport class N8nJsonLoader {\n\tconstructor(\n\t\tprivate context: IExecuteFunctions | ISupplyDataFunctions,\n\t\tprivate optionsPrefix = '',\n\t\tprivate textSplitter?: TextSplitter,\n\t) {}\n\n\tasync processAll(items?: INodeExecutionData[]): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\n\t\tif (!items) return [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst processedDocuments = await this.processItem(items[itemIndex], itemIndex);\n\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tasync processItem(item: INodeExecutionData, itemIndex: number): Promise<Document[]> {\n\t\tconst mode = this.context.getNodeParameter('jsonMode', itemIndex, 'allInputData') as\n\t\t\t| 'allInputData'\n\t\t\t| 'expressionData';\n\n\t\tconst pointers = this.context.getNodeParameter(\n\t\t\t`${this.optionsPrefix}pointers`,\n\t\t\titemIndex,\n\t\t\t'',\n\t\t) as string;\n\t\tconst pointersArray = pointers.split(',').map((pointer) => pointer.trim());\n\t\tconst metadata = getMetadataFiltersValues(this.context, itemIndex) ?? [];\n\n\t\tif (!item) return [];\n\n\t\tlet documentLoader: JSONLoader | TextLoader | null = null;\n\n\t\tif (mode === 'allInputData') {\n\t\t\tconst itemString = JSON.stringify(item.json);\n\t\t\tconst itemBlob = new Blob([itemString], { type: 'application/json' });\n\t\t\tdocumentLoader = new JSONLoader(itemBlob, pointersArray);\n\t\t}\n\n\t\tif (mode === 'expressionData') {\n\t\t\tconst dataString = this.context.getNodeParameter('jsonData', itemIndex) as string | object;\n\t\t\tif (typeof dataString === 'object') {\n\t\t\t\tconst itemBlob = new Blob([JSON.stringify(dataString)], { type: 'application/json' });\n\t\t\t\tdocumentLoader = new JSONLoader(itemBlob, pointersArray);\n\t\t\t}\n\n\t\t\tif (typeof dataString === 'string') {\n\t\t\t\tconst itemBlob = new Blob([dataString], { type: 'text/plain' });\n\t\t\t\tdocumentLoader = new TextLoader(itemBlob);\n\t\t\t}\n\t\t}\n\n\t\tif (documentLoader === null) {\n\t\t\t// This should never happen\n\t\t\tthrow new NodeOperationError(this.context.getNode(), 'Document loader is not initialized');\n\t\t}\n\n\t\tconst docs = this.textSplitter\n\t\t\t? await this.textSplitter.splitDocuments(await documentLoader.load())\n\t\t\t: await documentLoader.load();\n\n\t\tif (metadata) {\n\t\t\tdocs.forEach((doc) => {\n\t\t\t\tdoc.metadata = {\n\t\t\t\t\t...doc.metadata,\n\t\t\t\t\t...metadata,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t\treturn docs;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,kBAA2B;AAC3B,kBAA2B;AAC3B,0BAKO;AAEP,qBAAyC;AAElC,MAAM,cAAc;AAAA,EAC1B,YACS,SACA,gBAAgB,IAChB,cACP;AAHO;AACA;AACA;AAAA,EACN;AAAA,EAEH,MAAM,WAAW,OAAmD;AACnE,UAAM,OAAmB,CAAC;AAE1B,QAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,aAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,YAAM,qBAAqB,MAAM,KAAK,YAAY,MAAM,SAAS,GAAG,SAAS;AAE7E,WAAK,KAAK,GAAG,kBAAkB;AAAA,IAChC;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,YAAY,MAA0B,WAAwC;AACnF,UAAM,OAAO,KAAK,QAAQ,iBAAiB,YAAY,WAAW,cAAc;AAIhF,UAAM,WAAW,KAAK,QAAQ;AAAA,MAC7B,GAAG,KAAK,aAAa;AAAA,MACrB;AAAA,MACA;AAAA,IACD;AACA,UAAM,gBAAgB,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,YAAY,QAAQ,KAAK,CAAC;AACzE,UAAM,eAAW,yCAAyB,KAAK,SAAS,SAAS,KAAK,CAAC;AAEvE,QAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAI,iBAAiD;AAErD,QAAI,SAAS,gBAAgB;AAC5B,YAAM,aAAa,KAAK,UAAU,KAAK,IAAI;AAC3C,YAAM,WAAW,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpE,uBAAiB,IAAI,uBAAW,UAAU,aAAa;AAAA,IACxD;AAEA,QAAI,SAAS,kBAAkB;AAC9B,YAAM,aAAa,KAAK,QAAQ,iBAAiB,YAAY,SAAS;AACtE,UAAI,OAAO,eAAe,UAAU;AACnC,cAAM,WAAW,IAAI,KAAK,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpF,yBAAiB,IAAI,uBAAW,UAAU,aAAa;AAAA,MACxD;AAEA,UAAI,OAAO,eAAe,UAAU;AACnC,cAAM,WAAW,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,aAAa,CAAC;AAC9D,yBAAiB,IAAI,uBAAW,QAAQ;AAAA,MACzC;AAAA,IACD;AAEA,QAAI,mBAAmB,MAAM;AAE5B,YAAM,IAAI,uCAAmB,KAAK,QAAQ,QAAQ,GAAG,oCAAoC;AAAA,IAC1F;AAEA,UAAM,OAAO,KAAK,eACf,MAAM,KAAK,aAAa,eAAe,MAAM,eAAe,KAAK,CAAC,IAClE,MAAM,eAAe,KAAK;AAE7B,QAAI,UAAU;AACb,WAAK,QAAQ,CAAC,QAAQ;AACrB,YAAI,WAAW;AAAA,UACd,GAAG,IAAI;AAAA,UACP,GAAG;AAAA,QACJ;AAAA,MACD,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AACD;","names":[]}
1
+ {"version":3,"sources":["../../utils/N8nJsonLoader.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { JSONLoader } from '@langchain/classic/document_loaders/fs/json';\nimport { TextLoader } from '@langchain/classic/document_loaders/fs/text';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype ISupplyDataFunctions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { getMetadataFiltersValues } from './helpers';\n\nexport class N8nJsonLoader {\n\tconstructor(\n\t\tprivate context: IExecuteFunctions | ISupplyDataFunctions,\n\t\tprivate optionsPrefix = '',\n\t\tprivate textSplitter?: TextSplitter,\n\t) {}\n\n\tasync processAll(items?: INodeExecutionData[]): Promise<Document[]> {\n\t\tconst docs: Document[] = [];\n\n\t\tif (!items) return [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst processedDocuments = await this.processItem(items[itemIndex], itemIndex);\n\n\t\t\tdocs.push(...processedDocuments);\n\t\t}\n\n\t\treturn docs;\n\t}\n\n\tasync processItem(item: INodeExecutionData, itemIndex: number): Promise<Document[]> {\n\t\tconst mode = this.context.getNodeParameter('jsonMode', itemIndex, 'allInputData') as\n\t\t\t| 'allInputData'\n\t\t\t| 'expressionData';\n\n\t\tconst pointers = this.context.getNodeParameter(\n\t\t\t`${this.optionsPrefix}pointers`,\n\t\t\titemIndex,\n\t\t\t'',\n\t\t) as string;\n\t\tconst pointersArray = pointers.split(',').map((pointer) => pointer.trim());\n\t\tconst metadata = getMetadataFiltersValues(this.context, itemIndex) ?? [];\n\n\t\tif (!item) return [];\n\n\t\tlet documentLoader: JSONLoader | TextLoader | null = null;\n\n\t\tif (mode === 'allInputData') {\n\t\t\tconst itemString = JSON.stringify(item.json);\n\t\t\tconst itemBlob = new Blob([itemString], { type: 'application/json' });\n\t\t\tdocumentLoader = new JSONLoader(itemBlob, pointersArray);\n\t\t}\n\n\t\tif (mode === 'expressionData') {\n\t\t\tconst dataString = this.context.getNodeParameter('jsonData', itemIndex) as string | object;\n\t\t\tif (typeof dataString === 'object') {\n\t\t\t\tconst itemBlob = new Blob([JSON.stringify(dataString)], { type: 'application/json' });\n\t\t\t\tdocumentLoader = new JSONLoader(itemBlob, pointersArray);\n\t\t\t}\n\n\t\t\tif (typeof dataString === 'string') {\n\t\t\t\tconst itemBlob = new Blob([dataString], { type: 'text/plain' });\n\t\t\t\tdocumentLoader = new TextLoader(itemBlob);\n\t\t\t}\n\t\t}\n\n\t\tif (documentLoader === null) {\n\t\t\t// This should never happen\n\t\t\tthrow new NodeOperationError(this.context.getNode(), 'Document loader is not initialized');\n\t\t}\n\n\t\tconst docs = this.textSplitter\n\t\t\t? await this.textSplitter.splitDocuments(await documentLoader.load())\n\t\t\t: await documentLoader.load();\n\n\t\tif (metadata) {\n\t\t\tdocs.forEach((doc) => {\n\t\t\t\tdoc.metadata = {\n\t\t\t\t\t...doc.metadata,\n\t\t\t\t\t...metadata,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t\treturn docs;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,kBAA2B;AAC3B,kBAA2B;AAC3B,0BAKO;AAEP,qBAAyC;AAElC,MAAM,cAAc;AAAA,EAC1B,YACS,SACA,gBAAgB,IAChB,cACP;AAHO;AACA;AACA;AAAA,EACN;AAAA,EAEH,MAAM,WAAW,OAAmD;AACnE,UAAM,OAAmB,CAAC;AAE1B,QAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,aAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,YAAM,qBAAqB,MAAM,KAAK,YAAY,MAAM,SAAS,GAAG,SAAS;AAE7E,WAAK,KAAK,GAAG,kBAAkB;AAAA,IAChC;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,YAAY,MAA0B,WAAwC;AACnF,UAAM,OAAO,KAAK,QAAQ,iBAAiB,YAAY,WAAW,cAAc;AAIhF,UAAM,WAAW,KAAK,QAAQ;AAAA,MAC7B,GAAG,KAAK,aAAa;AAAA,MACrB;AAAA,MACA;AAAA,IACD;AACA,UAAM,gBAAgB,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,YAAY,QAAQ,KAAK,CAAC;AACzE,UAAM,eAAW,yCAAyB,KAAK,SAAS,SAAS,KAAK,CAAC;AAEvE,QAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAI,iBAAiD;AAErD,QAAI,SAAS,gBAAgB;AAC5B,YAAM,aAAa,KAAK,UAAU,KAAK,IAAI;AAC3C,YAAM,WAAW,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpE,uBAAiB,IAAI,uBAAW,UAAU,aAAa;AAAA,IACxD;AAEA,QAAI,SAAS,kBAAkB;AAC9B,YAAM,aAAa,KAAK,QAAQ,iBAAiB,YAAY,SAAS;AACtE,UAAI,OAAO,eAAe,UAAU;AACnC,cAAM,WAAW,IAAI,KAAK,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpF,yBAAiB,IAAI,uBAAW,UAAU,aAAa;AAAA,MACxD;AAEA,UAAI,OAAO,eAAe,UAAU;AACnC,cAAM,WAAW,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,aAAa,CAAC;AAC9D,yBAAiB,IAAI,uBAAW,QAAQ;AAAA,MACzC;AAAA,IACD;AAEA,QAAI,mBAAmB,MAAM;AAE5B,YAAM,IAAI,uCAAmB,KAAK,QAAQ,QAAQ,GAAG,oCAAoC;AAAA,IAC1F;AAEA,UAAM,OAAO,KAAK,eACf,MAAM,KAAK,aAAa,eAAe,MAAM,eAAe,KAAK,CAAC,IAClE,MAAM,eAAe,KAAK;AAE7B,QAAI,UAAU;AACb,WAAK,QAAQ,CAAC,QAAQ;AACrB,YAAI,WAAW;AAAA,UACd,GAAG,IAAI;AAAA,UACP,GAAG;AAAA,QACJ;AAAA,MACD,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AACD;","names":[]}
@@ -23,7 +23,7 @@ __export(N8nTool_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(N8nTool_exports);
25
25
  var import_tools = require("@langchain/core/tools");
26
- var import_output_parsers = require("langchain/output_parsers");
26
+ var import_output_parsers = require("@langchain/classic/output_parsers");
27
27
  var import_n8n_workflow = require("n8n-workflow");
28
28
  var import_zod = require("zod");
29
29
  const getSimplifiedType = (schema) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../utils/N8nTool.ts"],"sourcesContent":["import type { DynamicStructuredToolInput } from '@langchain/core/tools';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { StructuredOutputParser } from 'langchain/output_parsers';\nimport type { ISupplyDataFunctions, IDataObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, jsonParse, NodeOperationError } from 'n8n-workflow';\nimport type { ZodTypeAny } from 'zod';\nimport { ZodBoolean, ZodNullable, ZodNumber, ZodObject, ZodOptional } from 'zod';\n\nimport type { ZodObjectAny } from '../types/types';\n\nconst getSimplifiedType = (schema: ZodTypeAny) => {\n\tif (schema instanceof ZodObject) {\n\t\treturn 'object';\n\t} else if (schema instanceof ZodNumber) {\n\t\treturn 'number';\n\t} else if (schema instanceof ZodBoolean) {\n\t\treturn 'boolean';\n\t} else if (schema instanceof ZodNullable || schema instanceof ZodOptional) {\n\t\treturn getSimplifiedType(schema.unwrap());\n\t}\n\n\treturn 'string';\n};\n\nconst getParametersDescription = (parameters: Array<[string, ZodTypeAny]>) =>\n\tparameters\n\t\t.map(\n\t\t\t([name, schema]) =>\n\t\t\t\t`${name}: (description: ${schema.description ?? ''}, type: ${getSimplifiedType(schema)}, required: ${!schema.isOptional()})`,\n\t\t)\n\t\t.join(',\\n ');\n\nexport const prepareFallbackToolDescription = (toolDescription: string, schema: ZodObject<any>) => {\n\tlet description = `${toolDescription}`;\n\n\tconst toolParameters = Object.entries<ZodTypeAny>(schema.shape);\n\n\tif (toolParameters.length) {\n\t\tdescription += `\nTool expects valid stringified JSON object with ${toolParameters.length} properties.\nProperty names with description, type and required status:\n${getParametersDescription(toolParameters)}\nALL parameters marked as required must be provided`;\n\t}\n\n\treturn description;\n};\n\nexport class N8nTool extends DynamicStructuredTool<ZodObjectAny> {\n\tconstructor(\n\t\tprivate context: ISupplyDataFunctions,\n\t\tfields: DynamicStructuredToolInput<ZodObjectAny>,\n\t) {\n\t\tsuper(fields);\n\t}\n\n\tasDynamicTool(): DynamicTool {\n\t\tconst { name, func, schema, context, description } = this;\n\n\t\tconst parser = new StructuredOutputParser(schema);\n\n\t\tconst wrappedFunc = async function (query: string) {\n\t\t\tlet parsedQuery: object;\n\n\t\t\t// First we try to parse the query using the structured parser (Zod schema)\n\t\t\ttry {\n\t\t\t\tparsedQuery = await parser.parse(query);\n\t\t\t} catch (e) {\n\t\t\t\t// If we were unable to parse the query using the schema, we try to gracefully handle it\n\t\t\t\tlet dataFromModel;\n\n\t\t\t\ttry {\n\t\t\t\t\t// First we try to parse a JSON with more relaxed rules\n\t\t\t\t\tdataFromModel = jsonParse<IDataObject>(query, { acceptJSObject: true });\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// In case of error,\n\t\t\t\t\t// If model supplied a simple string instead of an object AND only one parameter expected, we try to recover the object structure\n\t\t\t\t\tif (Object.keys(schema.shape).length === 1) {\n\t\t\t\t\t\tconst parameterName = Object.keys(schema.shape)[0];\n\t\t\t\t\t\tdataFromModel = { [parameterName]: query };\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Finally throw an error if we were unable to parse the query\n\t\t\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t\t\t`Input is not a valid JSON: ${error.message}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we were able to parse the query with a fallback, we try to validate it using the schema\n\t\t\t\t// Here we will throw an error if the data still does not match the schema\n\t\t\t\tparsedQuery = schema.parse(dataFromModel);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Call tool function with parsed query\n\t\t\t\tconst result = await func(parsedQuery);\n\n\t\t\t\treturn result;\n\t\t\t} catch (e) {\n\t\t\t\tconst { index } = context.addInputData(NodeConnectionTypes.AiTool, [[{ json: { query } }]]);\n\t\t\t\tvoid context.addOutputData(NodeConnectionTypes.AiTool, index, e);\n\n\t\t\t\treturn e.toString();\n\t\t\t}\n\t\t};\n\n\t\treturn new DynamicTool({\n\t\t\tname,\n\t\t\tdescription: prepareFallbackToolDescription(description, schema),\n\t\t\tfunc: wrappedFunc,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAmD;AACnD,4BAAuC;AAEvC,0BAAmE;AAEnE,iBAA2E;AAI3E,MAAM,oBAAoB,CAAC,WAAuB;AACjD,MAAI,kBAAkB,sBAAW;AAChC,WAAO;AAAA,EACR,WAAW,kBAAkB,sBAAW;AACvC,WAAO;AAAA,EACR,WAAW,kBAAkB,uBAAY;AACxC,WAAO;AAAA,EACR,WAAW,kBAAkB,0BAAe,kBAAkB,wBAAa;AAC1E,WAAO,kBAAkB,OAAO,OAAO,CAAC;AAAA,EACzC;AAEA,SAAO;AACR;AAEA,MAAM,2BAA2B,CAAC,eACjC,WACE;AAAA,EACA,CAAC,CAAC,MAAM,MAAM,MACb,GAAG,IAAI,mBAAmB,OAAO,eAAe,EAAE,WAAW,kBAAkB,MAAM,CAAC,eAAe,CAAC,OAAO,WAAW,CAAC;AAC3H,EACC,KAAK,MAAM;AAEP,MAAM,iCAAiC,CAAC,iBAAyB,WAA2B;AAClG,MAAI,cAAc,GAAG,eAAe;AAEpC,QAAM,iBAAiB,OAAO,QAAoB,OAAO,KAAK;AAE9D,MAAI,eAAe,QAAQ;AAC1B,mBAAe;AAAA,kDACiC,eAAe,MAAM;AAAA;AAAA,EAErE,yBAAyB,cAAc,CAAC;AAAA;AAAA,EAEzC;AAEA,SAAO;AACR;AAEO,MAAM,gBAAgB,mCAAoC;AAAA,EAChE,YACS,SACR,QACC;AACD,UAAM,MAAM;AAHJ;AAAA,EAIT;AAAA,EAEA,gBAA6B;AAC5B,UAAM,EAAE,MAAM,MAAM,QAAQ,SAAS,YAAY,IAAI;AAErD,UAAM,SAAS,IAAI,6CAAuB,MAAM;AAEhD,UAAM,cAAc,eAAgB,OAAe;AAClD,UAAI;AAGJ,UAAI;AACH,sBAAc,MAAM,OAAO,MAAM,KAAK;AAAA,MACvC,SAAS,GAAG;AAEX,YAAI;AAEJ,YAAI;AAEH,8BAAgB,+BAAuB,OAAO,EAAE,gBAAgB,KAAK,CAAC;AAAA,QACvE,SAAS,OAAO;AAGf,cAAI,OAAO,KAAK,OAAO,KAAK,EAAE,WAAW,GAAG;AAC3C,kBAAM,gBAAgB,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC;AACjD,4BAAgB,EAAE,CAAC,aAAa,GAAG,MAAM;AAAA,UAC1C,OAAO;AAEN,kBAAM,IAAI;AAAA,cACT,QAAQ,QAAQ;AAAA,cAChB,8BAA8B,MAAM,OAAO;AAAA,YAC5C;AAAA,UACD;AAAA,QACD;AAIA,sBAAc,OAAO,MAAM,aAAa;AAAA,MACzC;AAEA,UAAI;AAEH,cAAM,SAAS,MAAM,KAAK,WAAW;AAErC,eAAO;AAAA,MACR,SAAS,GAAG;AACX,cAAM,EAAE,MAAM,IAAI,QAAQ,aAAa,wCAAoB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC1F,aAAK,QAAQ,cAAc,wCAAoB,QAAQ,OAAO,CAAC;AAE/D,eAAO,EAAE,SAAS;AAAA,MACnB;AAAA,IACD;AAEA,WAAO,IAAI,yBAAY;AAAA,MACtB;AAAA,MACA,aAAa,+BAA+B,aAAa,MAAM;AAAA,MAC/D,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AACD;","names":[]}
1
+ {"version":3,"sources":["../../utils/N8nTool.ts"],"sourcesContent":["import type { DynamicStructuredToolInput } from '@langchain/core/tools';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport { StructuredOutputParser } from '@langchain/classic/output_parsers';\nimport type { ISupplyDataFunctions, IDataObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, jsonParse, NodeOperationError } from 'n8n-workflow';\nimport type { ZodTypeAny } from 'zod';\nimport { ZodBoolean, ZodNullable, ZodNumber, ZodObject, ZodOptional } from 'zod';\n\nimport type { ZodObjectAny } from '../types/types';\n\nconst getSimplifiedType = (schema: ZodTypeAny) => {\n\tif (schema instanceof ZodObject) {\n\t\treturn 'object';\n\t} else if (schema instanceof ZodNumber) {\n\t\treturn 'number';\n\t} else if (schema instanceof ZodBoolean) {\n\t\treturn 'boolean';\n\t} else if (schema instanceof ZodNullable || schema instanceof ZodOptional) {\n\t\treturn getSimplifiedType(schema.unwrap());\n\t}\n\n\treturn 'string';\n};\n\nconst getParametersDescription = (parameters: Array<[string, ZodTypeAny]>) =>\n\tparameters\n\t\t.map(\n\t\t\t([name, schema]) =>\n\t\t\t\t`${name}: (description: ${schema.description ?? ''}, type: ${getSimplifiedType(schema)}, required: ${!schema.isOptional()})`,\n\t\t)\n\t\t.join(',\\n ');\n\nexport const prepareFallbackToolDescription = (toolDescription: string, schema: ZodObject<any>) => {\n\tlet description = `${toolDescription}`;\n\n\tconst toolParameters = Object.entries<ZodTypeAny>(schema.shape);\n\n\tif (toolParameters.length) {\n\t\tdescription += `\nTool expects valid stringified JSON object with ${toolParameters.length} properties.\nProperty names with description, type and required status:\n${getParametersDescription(toolParameters)}\nALL parameters marked as required must be provided`;\n\t}\n\n\treturn description;\n};\n\nexport class N8nTool extends DynamicStructuredTool<ZodObjectAny> {\n\tconstructor(\n\t\tprivate context: ISupplyDataFunctions,\n\t\tfields: DynamicStructuredToolInput<ZodObjectAny>,\n\t) {\n\t\tsuper(fields);\n\t}\n\n\tasDynamicTool(): DynamicTool {\n\t\tconst { name, func, schema, context, description } = this;\n\n\t\tconst parser = new StructuredOutputParser(schema);\n\n\t\tconst wrappedFunc = async function (query: string) {\n\t\t\tlet parsedQuery: object;\n\n\t\t\t// First we try to parse the query using the structured parser (Zod schema)\n\t\t\ttry {\n\t\t\t\tparsedQuery = await parser.parse(query);\n\t\t\t} catch (e) {\n\t\t\t\t// If we were unable to parse the query using the schema, we try to gracefully handle it\n\t\t\t\tlet dataFromModel;\n\n\t\t\t\ttry {\n\t\t\t\t\t// First we try to parse a JSON with more relaxed rules\n\t\t\t\t\tdataFromModel = jsonParse<IDataObject>(query, { acceptJSObject: true });\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// In case of error,\n\t\t\t\t\t// If model supplied a simple string instead of an object AND only one parameter expected, we try to recover the object structure\n\t\t\t\t\tif (Object.keys(schema.shape).length === 1) {\n\t\t\t\t\t\tconst parameterName = Object.keys(schema.shape)[0];\n\t\t\t\t\t\tdataFromModel = { [parameterName]: query };\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Finally throw an error if we were unable to parse the query\n\t\t\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t\t\t`Input is not a valid JSON: ${error.message}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If we were able to parse the query with a fallback, we try to validate it using the schema\n\t\t\t\t// Here we will throw an error if the data still does not match the schema\n\t\t\t\tparsedQuery = schema.parse(dataFromModel);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Call tool function with parsed query\n\t\t\t\tconst result = await func(parsedQuery);\n\n\t\t\t\treturn result;\n\t\t\t} catch (e) {\n\t\t\t\tconst { index } = context.addInputData(NodeConnectionTypes.AiTool, [[{ json: { query } }]]);\n\t\t\t\tvoid context.addOutputData(NodeConnectionTypes.AiTool, index, e);\n\n\t\t\t\treturn e.toString();\n\t\t\t}\n\t\t};\n\n\t\treturn new DynamicTool({\n\t\t\tname,\n\t\t\tdescription: prepareFallbackToolDescription(description, schema),\n\t\t\tfunc: wrappedFunc,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAmD;AACnD,4BAAuC;AAEvC,0BAAmE;AAEnE,iBAA2E;AAI3E,MAAM,oBAAoB,CAAC,WAAuB;AACjD,MAAI,kBAAkB,sBAAW;AAChC,WAAO;AAAA,EACR,WAAW,kBAAkB,sBAAW;AACvC,WAAO;AAAA,EACR,WAAW,kBAAkB,uBAAY;AACxC,WAAO;AAAA,EACR,WAAW,kBAAkB,0BAAe,kBAAkB,wBAAa;AAC1E,WAAO,kBAAkB,OAAO,OAAO,CAAC;AAAA,EACzC;AAEA,SAAO;AACR;AAEA,MAAM,2BAA2B,CAAC,eACjC,WACE;AAAA,EACA,CAAC,CAAC,MAAM,MAAM,MACb,GAAG,IAAI,mBAAmB,OAAO,eAAe,EAAE,WAAW,kBAAkB,MAAM,CAAC,eAAe,CAAC,OAAO,WAAW,CAAC;AAC3H,EACC,KAAK,MAAM;AAEP,MAAM,iCAAiC,CAAC,iBAAyB,WAA2B;AAClG,MAAI,cAAc,GAAG,eAAe;AAEpC,QAAM,iBAAiB,OAAO,QAAoB,OAAO,KAAK;AAE9D,MAAI,eAAe,QAAQ;AAC1B,mBAAe;AAAA,kDACiC,eAAe,MAAM;AAAA;AAAA,EAErE,yBAAyB,cAAc,CAAC;AAAA;AAAA,EAEzC;AAEA,SAAO;AACR;AAEO,MAAM,gBAAgB,mCAAoC;AAAA,EAChE,YACS,SACR,QACC;AACD,UAAM,MAAM;AAHJ;AAAA,EAIT;AAAA,EAEA,gBAA6B;AAC5B,UAAM,EAAE,MAAM,MAAM,QAAQ,SAAS,YAAY,IAAI;AAErD,UAAM,SAAS,IAAI,6CAAuB,MAAM;AAEhD,UAAM,cAAc,eAAgB,OAAe;AAClD,UAAI;AAGJ,UAAI;AACH,sBAAc,MAAM,OAAO,MAAM,KAAK;AAAA,MACvC,SAAS,GAAG;AAEX,YAAI;AAEJ,YAAI;AAEH,8BAAgB,+BAAuB,OAAO,EAAE,gBAAgB,KAAK,CAAC;AAAA,QACvE,SAAS,OAAO;AAGf,cAAI,OAAO,KAAK,OAAO,KAAK,EAAE,WAAW,GAAG;AAC3C,kBAAM,gBAAgB,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC;AACjD,4BAAgB,EAAE,CAAC,aAAa,GAAG,MAAM;AAAA,UAC1C,OAAO;AAEN,kBAAM,IAAI;AAAA,cACT,QAAQ,QAAQ;AAAA,cAChB,8BAA8B,MAAM,OAAO;AAAA,YAC5C;AAAA,UACD;AAAA,QACD;AAIA,sBAAc,OAAO,MAAM,aAAa;AAAA,MACzC;AAEA,UAAI;AAEH,cAAM,SAAS,MAAM,KAAK,WAAW;AAErC,eAAO;AAAA,MACR,SAAS,GAAG;AACX,cAAM,EAAE,MAAM,IAAI,QAAQ,aAAa,wCAAoB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC1F,aAAK,QAAQ,cAAc,wCAAoB,QAAQ,OAAO,CAAC;AAE/D,eAAO,EAAE,SAAS;AAAA,MACnB;AAAA,IACD;AAEA,WAAO,IAAI,yBAAY;AAAA,MACtB;AAAA,MACA,aAAa,+BAA+B,aAAa,MAAM;AAAA,MAC/D,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AACD;","names":[]}
@@ -43,16 +43,20 @@ function buildSteps(response, itemIndex) {
43
43
  if (step) {
44
44
  continue;
45
45
  }
46
+ const rawThoughtSignature = tool.action.metadata?.thoughtSignature;
47
+ const thoughtSignature = typeof rawThoughtSignature === "string" ? rawThoughtSignature : void 0;
48
+ const toolCall = {
49
+ id: typeof toolInput?.id === "string" ? toolInput.id : "reconstructed_call",
50
+ name: (0, import_n8n_workflow.nodeNameToToolName)(tool.action.nodeName),
51
+ args: toolInput,
52
+ type: "tool_call",
53
+ additional_kwargs: {
54
+ ...thoughtSignature && { thought_signature: thoughtSignature }
55
+ }
56
+ };
46
57
  const syntheticAIMessage = new import_messages.AIMessage({
47
58
  content: `Calling ${tool.action.nodeName} with input: ${JSON.stringify(toolInput)}`,
48
- tool_calls: [
49
- {
50
- id: toolInput?.id ?? "reconstructed_call",
51
- name: (0, import_n8n_workflow.nodeNameToToolName)(tool.action.nodeName),
52
- args: toolInput,
53
- type: "tool_call"
54
- }
55
- ]
59
+ tool_calls: [toolCall]
56
60
  });
57
61
  const toolResult = {
58
62
  action: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/buildSteps.ts"],"sourcesContent":["import { AIMessage } from '@langchain/core/messages';\nimport { nodeNameToToolName } from 'n8n-workflow';\nimport type { EngineResponse, IDataObject } from 'n8n-workflow';\n\nimport type { RequestResponseMetadata, ToolCallData } from './types';\n\n/**\n * Rebuilds the agent steps from previous tool call responses.\n * This is used to continue agent execution after tool calls have been made.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param response - The engine response containing tool call results\n * @param itemIndex - The current item index being processed\n * @returns Array of tool call data representing the agent steps\n */\nexport function buildSteps(\n\tresponse: EngineResponse<RequestResponseMetadata> | undefined,\n\titemIndex: number,\n): ToolCallData[] {\n\tconst steps: ToolCallData[] = [];\n\n\tif (response) {\n\t\tconst responses = response?.actionResponses ?? [];\n\n\t\tif (response.metadata?.previousRequests) {\n\t\t\tsteps.push.apply(steps, response.metadata.previousRequests);\n\t\t}\n\n\t\tfor (const tool of responses) {\n\t\t\tif (tool.action?.metadata?.itemIndex !== itemIndex) continue;\n\n\t\t\tconst toolInput: IDataObject = {\n\t\t\t\t...tool.action.input,\n\t\t\t\tid: tool.action.id,\n\t\t\t};\n\t\t\tif (!toolInput || !tool.data) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst step = steps.find((step) => step.action.toolCallId === toolInput.id);\n\t\t\tif (step) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Create a synthetic AI message for the messageLog\n\t\t\t// This represents the AI's decision to call the tool\n\t\t\tconst syntheticAIMessage = new AIMessage({\n\t\t\t\tcontent: `Calling ${tool.action.nodeName} with input: ${JSON.stringify(toolInput)}`,\n\t\t\t\ttool_calls: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: (toolInput?.id as string) ?? 'reconstructed_call',\n\t\t\t\t\t\tname: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\t\targs: toolInput,\n\t\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\n\t\t\tconst toolResult = {\n\t\t\t\taction: {\n\t\t\t\t\ttool: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\ttoolInput: (toolInput.input as IDataObject) || {},\n\t\t\t\t\tlog: toolInput.log || syntheticAIMessage.content,\n\t\t\t\t\tmessageLog: [syntheticAIMessage],\n\t\t\t\t\ttoolCallId: toolInput?.id,\n\t\t\t\t\ttype: toolInput.type || 'tool_call',\n\t\t\t\t},\n\t\t\t\tobservation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.map((item) => item?.json) ?? ''),\n\t\t\t};\n\n\t\t\tsteps.push(toolResult);\n\t\t}\n\t}\n\treturn steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA0B;AAC1B,0BAAmC;AAgB5B,SAAS,WACf,UACA,WACiB;AACjB,QAAM,QAAwB,CAAC;AAE/B,MAAI,UAAU;AACb,UAAM,YAAY,UAAU,mBAAmB,CAAC;AAEhD,QAAI,SAAS,UAAU,kBAAkB;AACxC,YAAM,KAAK,MAAM,OAAO,SAAS,SAAS,gBAAgB;AAAA,IAC3D;AAEA,eAAW,QAAQ,WAAW;AAC7B,UAAI,KAAK,QAAQ,UAAU,cAAc,UAAW;AAEpD,YAAM,YAAyB;AAAA,QAC9B,GAAG,KAAK,OAAO;AAAA,QACf,IAAI,KAAK,OAAO;AAAA,MACjB;AACA,UAAI,CAAC,aAAa,CAAC,KAAK,MAAM;AAC7B;AAAA,MACD;AAEA,YAAM,OAAO,MAAM,KAAK,CAACA,UAASA,MAAK,OAAO,eAAe,UAAU,EAAE;AACzE,UAAI,MAAM;AACT;AAAA,MACD;AAGA,YAAM,qBAAqB,IAAI,0BAAU;AAAA,QACxC,SAAS,WAAW,KAAK,OAAO,QAAQ,gBAAgB,KAAK,UAAU,SAAS,CAAC;AAAA,QACjF,YAAY;AAAA,UACX;AAAA,YACC,IAAK,WAAW,MAAiB;AAAA,YACjC,UAAM,wCAAmB,KAAK,OAAO,QAAQ;AAAA,YAC7C,MAAM;AAAA,YACN,MAAM;AAAA,UACP;AAAA,QACD;AAAA,MACD,CAAC;AAED,YAAM,aAAa;AAAA,QAClB,QAAQ;AAAA,UACP,UAAM,wCAAmB,KAAK,OAAO,QAAQ;AAAA,UAC7C,WAAY,UAAU,SAAyB,CAAC;AAAA,UAChD,KAAK,UAAU,OAAO,mBAAmB;AAAA,UACzC,YAAY,CAAC,kBAAkB;AAAA,UAC/B,YAAY,WAAW;AAAA,UACvB,MAAM,UAAU,QAAQ;AAAA,QACzB;AAAA,QACA,aAAa,KAAK,UAAU,KAAK,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,SAAS,MAAM,IAAI,KAAK,EAAE;AAAA,MAC3F;AAEA,YAAM,KAAK,UAAU;AAAA,IACtB;AAAA,EACD;AACA,SAAO;AACR;","names":["step"]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/buildSteps.ts"],"sourcesContent":["import { AIMessage } from '@langchain/core/messages';\nimport { nodeNameToToolName } from 'n8n-workflow';\nimport type { EngineResponse, IDataObject } from 'n8n-workflow';\n\nimport type { RequestResponseMetadata, ToolCallData } from './types';\n\n/**\n * Rebuilds the agent steps from previous tool call responses.\n * This is used to continue agent execution after tool calls have been made.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param response - The engine response containing tool call results\n * @param itemIndex - The current item index being processed\n * @returns Array of tool call data representing the agent steps\n */\nexport function buildSteps(\n\tresponse: EngineResponse<RequestResponseMetadata> | undefined,\n\titemIndex: number,\n): ToolCallData[] {\n\tconst steps: ToolCallData[] = [];\n\n\tif (response) {\n\t\tconst responses = response?.actionResponses ?? [];\n\n\t\tif (response.metadata?.previousRequests) {\n\t\t\tsteps.push.apply(steps, response.metadata.previousRequests);\n\t\t}\n\n\t\tfor (const tool of responses) {\n\t\t\tif (tool.action?.metadata?.itemIndex !== itemIndex) continue;\n\n\t\t\tconst toolInput: IDataObject = {\n\t\t\t\t...tool.action.input,\n\t\t\t\tid: tool.action.id,\n\t\t\t};\n\t\t\tif (!toolInput || !tool.data) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst step = steps.find((step) => step.action.toolCallId === toolInput.id);\n\t\t\tif (step) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Create a synthetic AI message for the messageLog\n\t\t\t// This represents the AI's decision to call the tool\n\t\t\t// Extract thought_signature from metadata if present (for Gemini 3)\n\t\t\tconst rawThoughtSignature = tool.action.metadata?.thoughtSignature;\n\t\t\tconst thoughtSignature =\n\t\t\t\ttypeof rawThoughtSignature === 'string' ? rawThoughtSignature : undefined;\n\n\t\t\t// Build the tool call object with thought_signature if present\n\t\t\t// The thought_signature must be part of the tool call itself for Gemini 3\n\t\t\tconst toolCall = {\n\t\t\t\tid: typeof toolInput?.id === 'string' ? toolInput.id : 'reconstructed_call',\n\t\t\t\tname: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\targs: toolInput,\n\t\t\t\ttype: 'tool_call' as const,\n\t\t\t\tadditional_kwargs: {\n\t\t\t\t\t...(thoughtSignature && { thought_signature: thoughtSignature }),\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst syntheticAIMessage = new AIMessage({\n\t\t\t\tcontent: `Calling ${tool.action.nodeName} with input: ${JSON.stringify(toolInput)}`,\n\t\t\t\ttool_calls: [toolCall],\n\t\t\t});\n\n\t\t\tconst toolResult = {\n\t\t\t\taction: {\n\t\t\t\t\ttool: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\ttoolInput: (toolInput.input as IDataObject) || {},\n\t\t\t\t\tlog: toolInput.log || syntheticAIMessage.content,\n\t\t\t\t\tmessageLog: [syntheticAIMessage],\n\t\t\t\t\ttoolCallId: toolInput?.id,\n\t\t\t\t\ttype: toolInput.type || 'tool_call',\n\t\t\t\t},\n\t\t\t\tobservation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.map((item) => item?.json) ?? ''),\n\t\t\t};\n\n\t\t\tsteps.push(toolResult);\n\t\t}\n\t}\n\treturn steps;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA0B;AAC1B,0BAAmC;AAgB5B,SAAS,WACf,UACA,WACiB;AACjB,QAAM,QAAwB,CAAC;AAE/B,MAAI,UAAU;AACb,UAAM,YAAY,UAAU,mBAAmB,CAAC;AAEhD,QAAI,SAAS,UAAU,kBAAkB;AACxC,YAAM,KAAK,MAAM,OAAO,SAAS,SAAS,gBAAgB;AAAA,IAC3D;AAEA,eAAW,QAAQ,WAAW;AAC7B,UAAI,KAAK,QAAQ,UAAU,cAAc,UAAW;AAEpD,YAAM,YAAyB;AAAA,QAC9B,GAAG,KAAK,OAAO;AAAA,QACf,IAAI,KAAK,OAAO;AAAA,MACjB;AACA,UAAI,CAAC,aAAa,CAAC,KAAK,MAAM;AAC7B;AAAA,MACD;AAEA,YAAM,OAAO,MAAM,KAAK,CAACA,UAASA,MAAK,OAAO,eAAe,UAAU,EAAE;AACzE,UAAI,MAAM;AACT;AAAA,MACD;AAIA,YAAM,sBAAsB,KAAK,OAAO,UAAU;AAClD,YAAM,mBACL,OAAO,wBAAwB,WAAW,sBAAsB;AAIjE,YAAM,WAAW;AAAA,QAChB,IAAI,OAAO,WAAW,OAAO,WAAW,UAAU,KAAK;AAAA,QACvD,UAAM,wCAAmB,KAAK,OAAO,QAAQ;AAAA,QAC7C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,mBAAmB;AAAA,UAClB,GAAI,oBAAoB,EAAE,mBAAmB,iBAAiB;AAAA,QAC/D;AAAA,MACD;AAEA,YAAM,qBAAqB,IAAI,0BAAU;AAAA,QACxC,SAAS,WAAW,KAAK,OAAO,QAAQ,gBAAgB,KAAK,UAAU,SAAS,CAAC;AAAA,QACjF,YAAY,CAAC,QAAQ;AAAA,MACtB,CAAC;AAED,YAAM,aAAa;AAAA,QAClB,QAAQ;AAAA,UACP,UAAM,wCAAmB,KAAK,OAAO,QAAQ;AAAA,UAC7C,WAAY,UAAU,SAAyB,CAAC;AAAA,UAChD,KAAK,UAAU,OAAO,mBAAmB;AAAA,UACzC,YAAY,CAAC,kBAAkB;AAAA,UAC/B,YAAY,WAAW;AAAA,UACvB,MAAM,UAAU,QAAQ;AAAA,QACzB;AAAA,QACA,aAAa,KAAK,UAAU,KAAK,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,SAAS,MAAM,IAAI,KAAK,EAAE;AAAA,MAC3F;AAEA,YAAM,KAAK,UAAU;AAAA,IACtB;AAAA,EACD;AACA,SAAO;AACR;","names":["step"]}
@@ -29,6 +29,23 @@ async function createEngineRequests(toolCalls, itemIndex, tools) {
29
29
  const nodeName = foundTool.metadata?.sourceNodeName;
30
30
  if (!nodeName) return void 0;
31
31
  const input = foundTool.metadata?.isFromToolkit ? { ...toolCall.toolInput, tool: toolCall.tool } : toolCall.toolInput;
32
+ let thoughtSignature;
33
+ if (toolCall.messageLog && Array.isArray(toolCall.messageLog)) {
34
+ for (const message of toolCall.messageLog) {
35
+ if (message && typeof message === "object" && "content" in message) {
36
+ const content = message.content;
37
+ if (Array.isArray(content)) {
38
+ for (const block of content) {
39
+ if (block && typeof block === "object" && "thoughtSignature" in block) {
40
+ thoughtSignature = block.thoughtSignature;
41
+ break;
42
+ }
43
+ }
44
+ }
45
+ if (thoughtSignature) break;
46
+ }
47
+ }
48
+ }
32
49
  return {
33
50
  actionType: "ExecutionNodeAction",
34
51
  nodeName,
@@ -36,7 +53,8 @@ async function createEngineRequests(toolCalls, itemIndex, tools) {
36
53
  type: import_n8n_workflow.NodeConnectionTypes.AiTool,
37
54
  id: toolCall.toolCallId,
38
55
  metadata: {
39
- itemIndex
56
+ itemIndex,
57
+ ...thoughtSignature && { thoughtSignature }
40
58
  }
41
59
  };
42
60
  }).filter((item) => item !== void 0);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/createEngineRequests.ts"],"sourcesContent":["import type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport { NodeConnectionTypes } from 'n8n-workflow';\nimport type { EngineRequest, IDataObject } from 'n8n-workflow';\n\nimport type { RequestResponseMetadata, ToolCallRequest } from './types';\n\n/**\n * Creates engine requests from tool calls.\n * Maps tool call information to the format expected by the n8n engine\n * for executing tool nodes.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param toolCalls - Array of tool call requests to convert\n * @param itemIndex - The current item index\n * @param tools - Array of available tools\n * @returns Array of engine request objects (filtered to remove undefined entries)\n */\nexport async function createEngineRequests(\n\ttoolCalls: ToolCallRequest[],\n\titemIndex: number,\n\ttools: Array<DynamicStructuredTool | Tool>,\n): Promise<EngineRequest<RequestResponseMetadata>['actions']> {\n\treturn toolCalls\n\t\t.map((toolCall) => {\n\t\t\t// First try to get from metadata (for toolkit tools)\n\t\t\tconst foundTool = tools.find((tool) => tool.name === toolCall.tool);\n\n\t\t\tif (!foundTool) return undefined;\n\n\t\t\tconst nodeName = foundTool.metadata?.sourceNodeName as string | undefined;\n\n\t\t\t// Ensure nodeName is defined\n\t\t\tif (!nodeName) return undefined;\n\n\t\t\t// For toolkit tools, include the tool name so the node knows which tool to execute\n\t\t\tconst input = foundTool.metadata?.isFromToolkit\n\t\t\t\t? { ...toolCall.toolInput, tool: toolCall.tool }\n\t\t\t\t: toolCall.toolInput;\n\n\t\t\treturn {\n\t\t\t\tactionType: 'ExecutionNodeAction' as const,\n\t\t\t\tnodeName,\n\t\t\t\tinput: input as IDataObject,\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tid: toolCall.toolCallId,\n\t\t\t\tmetadata: {\n\t\t\t\t\titemIndex,\n\t\t\t\t},\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is NonNullable<typeof item> => item !== undefined);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAoC;AAkBpC,eAAsB,qBACrB,WACA,WACA,OAC6D;AAC7D,SAAO,UACL,IAAI,CAAC,aAAa;AAElB,UAAM,YAAY,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,IAAI;AAElE,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,WAAW,UAAU,UAAU;AAGrC,QAAI,CAAC,SAAU,QAAO;AAGtB,UAAM,QAAQ,UAAU,UAAU,gBAC/B,EAAE,GAAG,SAAS,WAAW,MAAM,SAAS,KAAK,IAC7C,SAAS;AAEZ,WAAO;AAAA,MACN,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,MAAM,wCAAoB;AAAA,MAC1B,IAAI,SAAS;AAAA,MACb,UAAU;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC,EACA,OAAO,CAAC,SAA2C,SAAS,MAAS;AACxE;","names":[]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/createEngineRequests.ts"],"sourcesContent":["import type { DynamicStructuredTool, Tool } from '@langchain/classic/tools';\nimport { NodeConnectionTypes } from 'n8n-workflow';\nimport type { EngineRequest, IDataObject } from 'n8n-workflow';\n\nimport type { RequestResponseMetadata, ToolCallRequest } from './types';\n\n/**\n * Creates engine requests from tool calls.\n * Maps tool call information to the format expected by the n8n engine\n * for executing tool nodes.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param toolCalls - Array of tool call requests to convert\n * @param itemIndex - The current item index\n * @param tools - Array of available tools\n * @returns Array of engine request objects (filtered to remove undefined entries)\n */\nexport async function createEngineRequests(\n\ttoolCalls: ToolCallRequest[],\n\titemIndex: number,\n\ttools: Array<DynamicStructuredTool | Tool>,\n): Promise<EngineRequest<RequestResponseMetadata>['actions']> {\n\treturn toolCalls\n\t\t.map((toolCall) => {\n\t\t\t// First try to get from metadata (for toolkit tools)\n\t\t\tconst foundTool = tools.find((tool) => tool.name === toolCall.tool);\n\n\t\t\tif (!foundTool) return undefined;\n\n\t\t\tconst nodeName = foundTool.metadata?.sourceNodeName as string | undefined;\n\n\t\t\t// Ensure nodeName is defined\n\t\t\tif (!nodeName) return undefined;\n\n\t\t\t// For toolkit tools, include the tool name so the node knows which tool to execute\n\t\t\tconst input = foundTool.metadata?.isFromToolkit\n\t\t\t\t? { ...toolCall.toolInput, tool: toolCall.tool }\n\t\t\t\t: toolCall.toolInput;\n\n\t\t\t// Extract thought_signature from the AIMessage in messageLog (for Gemini 3)\n\t\t\tlet thoughtSignature: string | undefined;\n\t\t\tif (toolCall.messageLog && Array.isArray(toolCall.messageLog)) {\n\t\t\t\tfor (const message of toolCall.messageLog) {\n\t\t\t\t\t// Check if message has content that could contain thought_signature\n\t\t\t\t\tif (message && typeof message === 'object' && 'content' in message) {\n\t\t\t\t\t\tconst content = message.content;\n\t\t\t\t\t\t// Content can be string or array of content blocks\n\t\t\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\t\t\t// Look for thought_signature in content blocks\n\t\t\t\t\t\t\tfor (const block of content) {\n\t\t\t\t\t\t\t\tif (block && typeof block === 'object' && 'thoughtSignature' in block) {\n\t\t\t\t\t\t\t\t\tthoughtSignature = block.thoughtSignature as string;\n\t\t\t\t\t\t\t\t\tbreak;\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\tif (thoughtSignature) break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tactionType: 'ExecutionNodeAction' as const,\n\t\t\t\tnodeName,\n\t\t\t\tinput: input as IDataObject,\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tid: toolCall.toolCallId,\n\t\t\t\tmetadata: {\n\t\t\t\t\titemIndex,\n\t\t\t\t\t...(thoughtSignature && { thoughtSignature }),\n\t\t\t\t},\n\t\t\t};\n\t\t})\n\t\t.filter((item): item is NonNullable<typeof item> => item !== undefined);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAoC;AAkBpC,eAAsB,qBACrB,WACA,WACA,OAC6D;AAC7D,SAAO,UACL,IAAI,CAAC,aAAa;AAElB,UAAM,YAAY,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,IAAI;AAElE,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,WAAW,UAAU,UAAU;AAGrC,QAAI,CAAC,SAAU,QAAO;AAGtB,UAAM,QAAQ,UAAU,UAAU,gBAC/B,EAAE,GAAG,SAAS,WAAW,MAAM,SAAS,KAAK,IAC7C,SAAS;AAGZ,QAAI;AACJ,QAAI,SAAS,cAAc,MAAM,QAAQ,SAAS,UAAU,GAAG;AAC9D,iBAAW,WAAW,SAAS,YAAY;AAE1C,YAAI,WAAW,OAAO,YAAY,YAAY,aAAa,SAAS;AACnE,gBAAM,UAAU,QAAQ;AAExB,cAAI,MAAM,QAAQ,OAAO,GAAG;AAE3B,uBAAW,SAAS,SAAS;AAC5B,kBAAI,SAAS,OAAO,UAAU,YAAY,sBAAsB,OAAO;AACtE,mCAAmB,MAAM;AACzB;AAAA,cACD;AAAA,YACD;AAAA,UACD;AACA,cAAI,iBAAkB;AAAA,QACvB;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,MACN,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,MAAM,wCAAoB;AAAA,MAC1B,IAAI,SAAS;AAAA,MACb,UAAU;AAAA,QACT;AAAA,QACA,GAAI,oBAAoB,EAAE,iBAAiB;AAAA,MAC5C;AAAA,IACD;AAAA,EACD,CAAC,EACA,OAAO,CAAC,SAA2C,SAAS,MAAS;AACxE;","names":[]}
@@ -19,11 +19,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var agent_execution_exports = {};
20
20
  __export(agent_execution_exports, {
21
21
  buildSteps: () => import_buildSteps.buildSteps,
22
+ buildToolContext: () => import_memoryManagement.buildToolContext,
22
23
  createEngineRequests: () => import_createEngineRequests.createEngineRequests,
23
24
  loadMemory: () => import_memoryManagement.loadMemory,
24
25
  processEventStream: () => import_processEventStream.processEventStream,
25
- saveToMemory: () => import_memoryManagement.saveToMemory,
26
- saveToolResultsToMemory: () => import_memoryManagement.saveToolResultsToMemory
26
+ saveToMemory: () => import_memoryManagement.saveToMemory
27
27
  });
28
28
  module.exports = __toCommonJS(agent_execution_exports);
29
29
  var import_createEngineRequests = require("./createEngineRequests");
@@ -33,10 +33,10 @@ var import_memoryManagement = require("./memoryManagement");
33
33
  // Annotate the CommonJS export names for ESM import in node:
34
34
  0 && (module.exports = {
35
35
  buildSteps,
36
+ buildToolContext,
36
37
  createEngineRequests,
37
38
  loadMemory,
38
39
  processEventStream,
39
- saveToMemory,
40
- saveToolResultsToMemory
40
+ saveToMemory
41
41
  });
42
42
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/index.ts"],"sourcesContent":["/**\n * Agent Execution Utilities\n *\n * This module contains generalized utilities for agent execution that can be\n * reused across different agent types (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * These utilities support engine-based tool execution, where tool calls are\n * delegated to the n8n workflow engine instead of being executed inline.\n */\n\nexport { createEngineRequests } from './createEngineRequests';\nexport { buildSteps } from './buildSteps';\nexport { processEventStream } from './processEventStream';\nexport { loadMemory, saveToMemory, saveToolResultsToMemory } from './memoryManagement';\nexport type {\n\tToolCallRequest,\n\tToolCallData,\n\tAgentResult,\n\tRequestResponseMetadata,\n} from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,kCAAqC;AACrC,wBAA2B;AAC3B,gCAAmC;AACnC,8BAAkE;","names":[]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/index.ts"],"sourcesContent":["/**\n * Agent Execution Utilities\n *\n * This module contains generalized utilities for agent execution that can be\n * reused across different agent types (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * These utilities support engine-based tool execution, where tool calls are\n * delegated to the n8n workflow engine instead of being executed inline.\n */\n\nexport { createEngineRequests } from './createEngineRequests';\nexport { buildSteps } from './buildSteps';\nexport { processEventStream } from './processEventStream';\nexport { loadMemory, saveToMemory, buildToolContext } from './memoryManagement';\nexport type {\n\tToolCallRequest,\n\tToolCallData,\n\tAgentResult,\n\tRequestResponseMetadata,\n} from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,kCAAqC;AACrC,wBAA2B;AAC3B,gCAAmC;AACnC,8BAA2D;","names":[]}
@@ -18,12 +18,17 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var memoryManagement_exports = {};
20
20
  __export(memoryManagement_exports, {
21
+ buildToolContext: () => buildToolContext,
21
22
  loadMemory: () => loadMemory,
22
- saveToMemory: () => saveToMemory,
23
- saveToolResultsToMemory: () => saveToolResultsToMemory
23
+ saveToMemory: () => saveToMemory
24
24
  });
25
25
  module.exports = __toCommonJS(memoryManagement_exports);
26
26
  var import_messages = require("@langchain/core/messages");
27
+ function buildToolContext(steps) {
28
+ return steps.map(
29
+ (step) => `Tool: ${step.action.tool}, Input: ${JSON.stringify(step.action.toolInput)}, Result: ${step.observation}`
30
+ ).join("; ");
31
+ }
27
32
  async function loadMemory(memory, model, maxTokens) {
28
33
  if (!memory) {
29
34
  return void 0;
@@ -42,25 +47,21 @@ async function loadMemory(memory, model, maxTokens) {
42
47
  }
43
48
  return chatHistory;
44
49
  }
45
- async function saveToMemory(input, output, memory) {
50
+ async function saveToMemory(input, output, memory, steps) {
46
51
  if (!output || !memory) {
47
52
  return;
48
53
  }
49
- await memory.saveContext({ input }, { output });
50
- }
51
- async function saveToolResultsToMemory(input, toolResults, memory) {
52
- if (!memory || !toolResults.length) {
53
- return;
54
- }
55
- for (const result of toolResults) {
56
- const toolMessage = `Tool: ${result.action.tool}, Input: ${JSON.stringify(result.action.toolInput)}, Result: ${result.observation}`;
57
- await memory.saveContext({ input }, { output: toolMessage });
54
+ let fullOutput = output;
55
+ if (steps && steps.length > 0) {
56
+ const toolContext = buildToolContext(steps);
57
+ fullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;
58
58
  }
59
+ await memory.saveContext({ input }, { output: fullOutput });
59
60
  }
60
61
  // Annotate the CommonJS export names for ESM import in node:
61
62
  0 && (module.exports = {
63
+ buildToolContext,
62
64
  loadMemory,
63
- saveToMemory,
64
- saveToolResultsToMemory
65
+ saveToMemory
65
66
  });
66
67
  //# sourceMappingURL=memoryManagement.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/memoryManagement.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { trimMessages } from '@langchain/core/messages';\nimport type { BaseChatMemory } from 'langchain/memory';\n\nimport type { ToolCallData } from './types';\n\n/**\n * Loads chat history from memory and optionally trims it to fit within token limits.\n *\n * @param memory - The memory instance to load from\n * @param model - Optional chat model for token counting (required if maxTokens is specified)\n * @param maxTokens - Optional maximum number of tokens to load from memory\n * @returns Array of base messages representing the chat history\n *\n * @example\n * ```typescript\n * // Load all history\n * const messages = await loadMemory(memory);\n *\n * // Load with token limit\n * const messages = await loadMemory(memory, model, 2000);\n * ```\n */\nexport async function loadMemory(\n\tmemory?: BaseChatMemory,\n\tmodel?: BaseChatModel,\n\tmaxTokens?: number,\n): Promise<BaseMessage[] | undefined> {\n\tif (!memory) {\n\t\treturn undefined;\n\t}\n\tconst memoryVariables = await memory.loadMemoryVariables({});\n\tlet chatHistory = (memoryVariables['chat_history'] as BaseMessage[]) || [];\n\n\t// Trim messages if token limit is specified and model is available\n\tif (maxTokens && model) {\n\t\tchatHistory = await trimMessages(chatHistory, {\n\t\t\tstrategy: 'last',\n\t\t\tmaxTokens,\n\t\t\ttokenCounter: model,\n\t\t\tincludeSystem: true,\n\t\t\tstartOn: 'human',\n\t\t\tallowPartial: true,\n\t\t});\n\t}\n\n\treturn chatHistory;\n}\n\n/**\n * Saves a conversation turn (user input + agent output) to memory.\n *\n * @param memory - The memory instance to save to\n * @param input - The user input/prompt\n * @param output - The agent's output/response\n *\n * @example\n * ```typescript\n * await saveToMemory(memory, 'What is 2+2?', 'The answer is 4');\n * ```\n */\nexport async function saveToMemory(\n\tinput: string,\n\toutput: string,\n\tmemory?: BaseChatMemory,\n): Promise<void> {\n\tif (!output || !memory) {\n\t\treturn;\n\t}\n\n\tawait memory.saveContext({ input }, { output });\n}\n\n/**\n * Saves tool call results to memory as formatted messages.\n *\n * This preserves the full conversation including tool interactions,\n * which is important for agents that need to see their tool usage history.\n *\n * @param memory - The memory instance to save to\n * @param input - The user input that triggered the tool calls\n * @param toolResults - Array of tool call results to save\n *\n * @example\n * ```typescript\n * await saveToolResultsToMemory(memory, 'Calculate 2+2', [{\n * action: {\n * tool: 'calculator',\n * toolInput: { expression: '2+2' },\n * log: 'Using calculator',\n * toolCallId: 'call_123',\n * type: 'tool_call'\n * },\n * observation: '4'\n * }]);\n * ```\n */\nexport async function saveToolResultsToMemory(\n\tinput: string,\n\ttoolResults: ToolCallData[],\n\tmemory?: BaseChatMemory,\n): Promise<void> {\n\tif (!memory || !toolResults.length) {\n\t\treturn;\n\t}\n\n\t// Save each tool call as a formatted message\n\tfor (const result of toolResults) {\n\t\tconst toolMessage = `Tool: ${result.action.tool}, Input: ${JSON.stringify(result.action.toolInput)}, Result: ${result.observation}`;\n\t\tawait memory.saveContext({ input }, { output: toolMessage });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAA6B;AAsB7B,eAAsB,WACrB,QACA,OACA,WACqC;AACrC,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,EACR;AACA,QAAM,kBAAkB,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAC3D,MAAI,cAAe,gBAAgB,cAAc,KAAuB,CAAC;AAGzE,MAAI,aAAa,OAAO;AACvB,kBAAc,UAAM,8BAAa,aAAa;AAAA,MAC7C,UAAU;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,eAAe;AAAA,MACf,SAAS;AAAA,MACT,cAAc;AAAA,IACf,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAcA,eAAsB,aACrB,OACA,QACA,QACgB;AAChB,MAAI,CAAC,UAAU,CAAC,QAAQ;AACvB;AAAA,EACD;AAEA,QAAM,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,OAAO,CAAC;AAC/C;AA0BA,eAAsB,wBACrB,OACA,aACA,QACgB;AAChB,MAAI,CAAC,UAAU,CAAC,YAAY,QAAQ;AACnC;AAAA,EACD;AAGA,aAAW,UAAU,aAAa;AACjC,UAAM,cAAc,SAAS,OAAO,OAAO,IAAI,YAAY,KAAK,UAAU,OAAO,OAAO,SAAS,CAAC,aAAa,OAAO,WAAW;AACjI,UAAM,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,QAAQ,YAAY,CAAC;AAAA,EAC5D;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/memoryManagement.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { trimMessages } from '@langchain/core/messages';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\n\nimport type { ToolCallData } from './types';\n\n/**\n * Builds a formatted string representation of tool calls for memory storage.\n * This creates a consistent format that can be used across both streaming and non-streaming modes.\n *\n * @param steps - Array of tool call data with actions and observations\n * @returns Formatted string of tool calls separated by semicolons\n *\n * @example\n * ```typescript\n * const context = buildToolContext([{\n * action: { tool: 'calculator', toolInput: { expression: '2+2' }, ... },\n * observation: '4'\n * }]);\n * // Returns: \"Tool: calculator, Input: {\"expression\":\"2+2\"}, Result: 4\"\n * ```\n */\nexport function buildToolContext(steps: ToolCallData[]): string {\n\treturn steps\n\t\t.map(\n\t\t\t(step) =>\n\t\t\t\t`Tool: ${step.action.tool}, Input: ${JSON.stringify(step.action.toolInput)}, Result: ${step.observation}`,\n\t\t)\n\t\t.join('; ');\n}\n\n/**\n * Loads chat history from memory and optionally trims it to fit within token limits.\n *\n * @param memory - The memory instance to load from\n * @param model - Optional chat model for token counting (required if maxTokens is specified)\n * @param maxTokens - Optional maximum number of tokens to load from memory\n * @returns Array of base messages representing the chat history\n *\n * @example\n * ```typescript\n * // Load all history\n * const messages = await loadMemory(memory);\n *\n * // Load with token limit\n * const messages = await loadMemory(memory, model, 2000);\n * ```\n */\nexport async function loadMemory(\n\tmemory?: BaseChatMemory,\n\tmodel?: BaseChatModel,\n\tmaxTokens?: number,\n): Promise<BaseMessage[] | undefined> {\n\tif (!memory) {\n\t\treturn undefined;\n\t}\n\tconst memoryVariables = await memory.loadMemoryVariables({});\n\tlet chatHistory = (memoryVariables['chat_history'] as BaseMessage[]) || [];\n\n\t// Trim messages if token limit is specified and model is available\n\tif (maxTokens && model) {\n\t\tchatHistory = await trimMessages(chatHistory, {\n\t\t\tstrategy: 'last',\n\t\t\tmaxTokens,\n\t\t\ttokenCounter: model,\n\t\t\tincludeSystem: true,\n\t\t\tstartOn: 'human',\n\t\t\tallowPartial: true,\n\t\t});\n\t}\n\n\treturn chatHistory;\n}\n\n/**\n * Saves a conversation turn (user input + agent output) to memory.\n *\n * @param memory - The memory instance to save to\n * @param input - The user input/prompt\n * @param output - The agent's output/response\n *\n * @example\n * ```typescript\n * await saveToMemory(memory, 'What is 2+2?', 'The answer is 4');\n * ```\n */\nexport async function saveToMemory(\n\tinput: string,\n\toutput: string,\n\tmemory?: BaseChatMemory,\n\tsteps?: ToolCallData[],\n): Promise<void> {\n\tif (!output || !memory) {\n\t\treturn;\n\t}\n\tlet fullOutput = output;\n\tif (steps && steps.length > 0) {\n\t\tconst toolContext = buildToolContext(steps);\n\t\tfullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;\n\t}\n\n\tawait memory.saveContext({ input }, { output: fullOutput });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAA6B;AAqBtB,SAAS,iBAAiB,OAA+B;AAC/D,SAAO,MACL;AAAA,IACA,CAAC,SACA,SAAS,KAAK,OAAO,IAAI,YAAY,KAAK,UAAU,KAAK,OAAO,SAAS,CAAC,aAAa,KAAK,WAAW;AAAA,EACzG,EACC,KAAK,IAAI;AACZ;AAmBA,eAAsB,WACrB,QACA,OACA,WACqC;AACrC,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,EACR;AACA,QAAM,kBAAkB,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAC3D,MAAI,cAAe,gBAAgB,cAAc,KAAuB,CAAC;AAGzE,MAAI,aAAa,OAAO;AACvB,kBAAc,UAAM,8BAAa,aAAa;AAAA,MAC7C,UAAU;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,eAAe;AAAA,MACf,SAAS;AAAA,MACT,cAAc;AAAA,IACf,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAcA,eAAsB,aACrB,OACA,QACA,QACA,OACgB;AAChB,MAAI,CAAC,UAAU,CAAC,QAAQ;AACvB;AAAA,EACD;AACA,MAAI,aAAa;AACjB,MAAI,SAAS,MAAM,SAAS,GAAG;AAC9B,UAAM,cAAc,iBAAiB,KAAK;AAC1C,iBAAa,gBAAgB,WAAW,KAAK,UAAU;AAAA,EACxD;AAEA,QAAM,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,QAAQ,WAAW,CAAC;AAC3D;","names":[]}
@@ -21,14 +21,10 @@ __export(processEventStream_exports, {
21
21
  processEventStream: () => processEventStream
22
22
  });
23
23
  module.exports = __toCommonJS(processEventStream_exports);
24
- var import_memoryManagement = require("./memoryManagement");
25
- async function processEventStream(ctx, eventStream, itemIndex, returnIntermediateSteps = false, memory, input) {
24
+ async function processEventStream(ctx, eventStream, itemIndex) {
26
25
  const agentResult = {
27
26
  output: ""
28
27
  };
29
- if (returnIntermediateSteps) {
30
- agentResult.intermediateSteps = [];
31
- }
32
28
  const toolCalls = [];
33
29
  ctx.sendChunk("begin", itemIndex);
34
30
  for await (const event of eventStream) {
@@ -66,45 +62,6 @@ async function processEventStream(ctx, eventStream, itemIndex, returnIntermediat
66
62
  messageLog: [output]
67
63
  });
68
64
  }
69
- if (returnIntermediateSteps) {
70
- for (const toolCall of output.tool_calls) {
71
- agentResult.intermediateSteps?.push({
72
- action: {
73
- tool: toolCall.name,
74
- toolInput: toolCall.args,
75
- log: output.content || `Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,
76
- messageLog: [output],
77
- // Include the full LLM response
78
- toolCallId: toolCall.id || "unknown",
79
- type: toolCall.type || "tool_call"
80
- },
81
- observation: ""
82
- });
83
- }
84
- }
85
- }
86
- }
87
- break;
88
- case "on_tool_end":
89
- if (returnIntermediateSteps && event.data && agentResult.intermediateSteps.length > 0) {
90
- const toolData = event.data;
91
- const matchingStep = agentResult.intermediateSteps?.find(
92
- (step) => !step.observation && step.action.tool === event.name
93
- );
94
- if (matchingStep) {
95
- matchingStep.observation = toolData.output || "";
96
- if (matchingStep.observation && input) {
97
- await (0, import_memoryManagement.saveToolResultsToMemory)(
98
- input,
99
- [
100
- {
101
- action: matchingStep.action,
102
- observation: matchingStep.observation
103
- }
104
- ],
105
- memory
106
- );
107
- }
108
65
  }
109
66
  }
110
67
  break;
@@ -113,9 +70,6 @@ async function processEventStream(ctx, eventStream, itemIndex, returnIntermediat
113
70
  }
114
71
  }
115
72
  ctx.sendChunk("end", itemIndex);
116
- if (input && agentResult.output) {
117
- await (0, import_memoryManagement.saveToMemory)(input, agentResult.output, memory);
118
- }
119
73
  if (toolCalls.length > 0) {
120
74
  agentResult.toolCalls = toolCalls;
121
75
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/processEventStream.ts"],"sourcesContent":["import type { StreamEvent } from '@langchain/core/dist/tracers/event_stream';\nimport type { IterableReadableStream } from '@langchain/core/dist/utils/stream';\nimport type { AIMessageChunk, MessageContentText } from '@langchain/core/messages';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type { IExecuteFunctions } from 'n8n-workflow';\n\nimport { saveToMemory, saveToolResultsToMemory } from './memoryManagement';\nimport type { AgentResult, ToolCallRequest } from './types';\n\n/**\n * Processes the event stream from a streaming agent execution.\n * Handles streaming chunks, tool calls, and intermediate steps.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param ctx - The execution context\n * @param eventStream - The stream of events from the agent\n * @param itemIndex - The current item index\n * @param returnIntermediateSteps - Whether to capture intermediate steps\n * @param memory - Optional memory for saving context\n * @param input - The original input prompt\n * @returns AgentResult containing output and optional tool calls/steps\n */\nexport async function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n\treturnIntermediateSteps: boolean = false,\n\tmemory?: BaseChatMemory,\n\tinput?: string,\n): Promise<AgentResult> {\n\tconst agentResult: AgentResult = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tconst toolCalls: ToolCallRequest[] = [];\n\n\tctx.sendChunk('begin', itemIndex);\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\tif (message?.type === 'text') {\n\t\t\t\t\t\t\t\tchunkText += (message as MessageContentText)?.text;\n\t\t\t\t\t\t\t}\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', itemIndex, 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 (event.data) {\n\t\t\t\t\tconst chatModelData = event.data;\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\t// Collect tool calls for request building\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\toutput.content ||\n\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\tmessageLog: [output],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Also add to intermediate steps if needed\n\t\t\t\t\t\tif (returnIntermediateSteps) {\n\t\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\t\tagentResult.intermediateSteps?.push({\n\t\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\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\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tobservation: '',\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 { output?: string };\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\n\t\t\t\t\t\t// Save tool result to memory\n\t\t\t\t\t\tif (matchingStep.observation && input) {\n\t\t\t\t\t\t\tawait saveToolResultsToMemory(\n\t\t\t\t\t\t\t\tinput,\n\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\taction: matchingStep.action,\n\t\t\t\t\t\t\t\t\t\tobservation: matchingStep.observation,\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\tmemory,\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\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\t// Save conversation to memory if memory is connected\n\tif (input && agentResult.output) {\n\t\tawait saveToMemory(input, agentResult.output, memory);\n\t}\n\n\t// Include collected tool calls in the result\n\tif (toolCalls.length > 0) {\n\t\tagentResult.toolCalls = toolCalls;\n\t}\n\n\treturn agentResult;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/processEventStream.ts"],"sourcesContent":["import type { StreamEvent } from '@langchain/core/dist/tracers/event_stream';\nimport type { IterableReadableStream } from '@langchain/core/dist/utils/stream';\nimport type { AIMessageChunk, MessageContentText } from '@langchain/core/messages';\nimport type { IExecuteFunctions } from 'n8n-workflow';\n\nimport type { AgentResult, ToolCallRequest } from './types';\n\n/**\n * Processes the event stream from a streaming agent execution.\n * Handles streaming chunks, tool calls, and intermediate steps.\n *\n * This is a generalized version that can be used across different agent types\n * (Tools Agent, OpenAI Functions Agent, etc.).\n *\n * @param ctx - The execution context\n * @param eventStream - The stream of events from the agent\n * @param itemIndex - The current item index\n * @returns AgentResult containing output and optional tool calls/steps\n */\nexport async function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n): Promise<AgentResult> {\n\tconst agentResult: AgentResult = {\n\t\toutput: '',\n\t};\n\n\tconst toolCalls: ToolCallRequest[] = [];\n\n\tctx.sendChunk('begin', itemIndex);\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\tif (message?.type === 'text') {\n\t\t\t\t\t\t\t\tchunkText += (message as MessageContentText)?.text;\n\t\t\t\t\t\t\t}\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', itemIndex, 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 (event.data) {\n\t\t\t\t\tconst chatModelData = event.data;\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\t// Collect tool calls for request building\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\toutput.content ||\n\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\tmessageLog: [output],\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\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\t// Include collected tool calls in the result\n\tif (toolCalls.length > 0) {\n\t\tagentResult.toolCalls = toolCalls;\n\t}\n\n\treturn agentResult;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,eAAsB,mBACrB,KACA,aACA,WACuB;AACvB,QAAM,cAA2B;AAAA,IAChC,QAAQ;AAAA,EACT;AAEA,QAAM,YAA+B,CAAC;AAEtC,MAAI,UAAU,SAAS,SAAS;AAChC,mBAAiB,SAAS,aAAa;AAEtC,YAAQ,MAAM,OAAO;AAAA,MACpB,KAAK;AACJ,cAAM,QAAQ,MAAM,MAAM;AAC1B,YAAI,OAAO,SAAS;AACnB,gBAAM,eAAe,MAAM;AAC3B,cAAI,YAAY;AAChB,cAAI,MAAM,QAAQ,YAAY,GAAG;AAChC,uBAAW,WAAW,cAAc;AACnC,kBAAI,SAAS,SAAS,QAAQ;AAC7B,6BAAc,SAAgC;AAAA,cAC/C;AAAA,YACD;AAAA,UACD,WAAW,OAAO,iBAAiB,UAAU;AAC5C,wBAAY;AAAA,UACb;AACA,cAAI,UAAU,QAAQ,WAAW,SAAS;AAE1C,sBAAY,UAAU;AAAA,QACvB;AACA;AAAA,MACD,KAAK;AAEJ,YAAI,MAAM,MAAM;AACf,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,SAAS,cAAc;AAG7B,cAAI,QAAQ,cAAc,OAAO,WAAW,SAAS,GAAG;AAEvD,uBAAW,YAAY,OAAO,YAAY;AACzC,wBAAU,KAAK;AAAA,gBACd,MAAM,SAAS;AAAA,gBACf,WAAW,SAAS;AAAA,gBACpB,YAAY,SAAS,MAAM;AAAA,gBAC3B,MAAM,SAAS,QAAQ;AAAA,gBACvB,KACC,OAAO,WACP,WAAW,SAAS,IAAI,gBAAgB,KAAK,UAAU,SAAS,IAAI,CAAC;AAAA,gBACtE,YAAY,CAAC,MAAM;AAAA,cACpB,CAAC;AAAA,YACF;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AACC;AAAA,IACF;AAAA,EACD;AACA,MAAI,UAAU,OAAO,SAAS;AAG9B,MAAI,UAAU,SAAS,GAAG;AACzB,gBAAY,YAAY;AAAA,EACzB;AAEA,SAAO;AACR;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/agent-execution/types.ts"],"sourcesContent":["import type { AIMessage } from '@langchain/core/messages';\nimport type { IDataObject, GenericValue } from 'n8n-workflow';\n\n/**\n * Represents a tool call request from an LLM.\n * This is a generic format that can be used across different agent types.\n */\nexport type ToolCallRequest = {\n\t/** The name of the tool to call */\n\ttool: string;\n\t/** The input arguments for the tool */\n\ttoolInput: Record<string, unknown>;\n\t/** Unique identifier for this tool call */\n\ttoolCallId: string;\n\t/** Type of the tool call (e.g., 'tool_call', 'function') */\n\ttype?: string;\n\t/** Log message or description */\n\tlog?: string;\n\t/** Full message log including LLM response */\n\tmessageLog?: unknown[];\n};\n\n/**\n * Represents a tool call action and its observation result.\n * Used for building agent steps and maintaining conversation context.\n */\nexport type ToolCallData = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string | number | true | object;\n\t\tmessageLog?: AIMessage[];\n\t\ttoolCallId: IDataObject | GenericValue | GenericValue[] | IDataObject[];\n\t\ttype: string | number | true | object;\n\t};\n\tobservation: string;\n};\n\n/**\n * Result from an agent execution, optionally including tool calls and intermediate steps.\n */\nexport type AgentResult = {\n\t/** The final output from the agent */\n\toutput: string;\n\t/** Tool calls that need to be executed */\n\ttoolCalls?: ToolCallRequest[];\n\t/** Intermediate steps showing the agent's reasoning */\n\tintermediateSteps?: ToolCallData[];\n};\n\n/**\n * Metadata for engine requests and responses.\n */\nexport type RequestResponseMetadata = {\n\t/** Item index being processed */\n\titemIndex?: number;\n\t/** Previous tool call requests (for multi-turn conversations) */\n\tpreviousRequests?: ToolCallData[];\n\t/** Current iteration count (for max iterations enforcement) */\n\titerationCount?: number;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../utils/agent-execution/types.ts"],"sourcesContent":["import type { AIMessage } from '@langchain/core/messages';\nimport type { IDataObject, GenericValue } from 'n8n-workflow';\n\n/**\n * Represents a tool call request from an LLM.\n * This is a generic format that can be used across different agent types.\n */\nexport type ToolCallRequest = {\n\t/** The name of the tool to call */\n\ttool: string;\n\t/** The input arguments for the tool */\n\ttoolInput: Record<string, unknown>;\n\t/** Unique identifier for this tool call */\n\ttoolCallId: string;\n\t/** Type of the tool call (e.g., 'tool_call', 'function') */\n\ttype?: string;\n\t/** Log message or description */\n\tlog?: string;\n\t/** Full message log including LLM response */\n\tmessageLog?: unknown[];\n};\n\n/**\n * Represents a tool call action and its observation result.\n * Used for building agent steps and maintaining conversation context.\n */\nexport type ToolCallData = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string | number | true | object;\n\t\tmessageLog?: AIMessage[];\n\t\ttoolCallId: IDataObject | GenericValue | GenericValue[] | IDataObject[];\n\t\ttype: string | number | true | object;\n\t};\n\tobservation: string;\n};\n\n/**\n * Result from an agent execution, optionally including tool calls and intermediate steps.\n */\nexport type AgentResult = {\n\t/** The final output from the agent */\n\toutput: string;\n\t/** Tool calls that need to be executed */\n\ttoolCalls?: ToolCallRequest[];\n\t/** Intermediate steps showing the agent's reasoning */\n\tintermediateSteps?: ToolCallData[];\n};\n\n/**\n * Metadata for engine requests and responses.\n */\nexport type RequestResponseMetadata = {\n\t/** Item index being processed */\n\titemIndex?: number;\n\t/** Previous tool call requests (for multi-turn conversations) */\n\tpreviousRequests?: ToolCallData[];\n\t/** Current iteration count (for max iterations enforcement) */\n\titerationCount?: number;\n\t/** Thought signature for Gemini 3 tool calls */\n\tthoughtSignature?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var fromAIToolFactory_exports = {};
20
+ __export(fromAIToolFactory_exports, {
21
+ createToolFromNode: () => createToolFromNode,
22
+ createZodSchemaFromArgs: () => createZodSchemaFromArgs,
23
+ extractFromAIParameters: () => extractFromAIParameters
24
+ });
25
+ module.exports = __toCommonJS(fromAIToolFactory_exports);
26
+ var import_tools = require("@langchain/core/tools");
27
+ var import_n8n_workflow = require("n8n-workflow");
28
+ var import_zod = require("zod");
29
+ function extractFromAIParameters(nodeParameters) {
30
+ const collectedArguments = [];
31
+ (0, import_n8n_workflow.traverseNodeParameters)(nodeParameters, collectedArguments);
32
+ const uniqueArgsMap = /* @__PURE__ */ new Map();
33
+ for (const arg of collectedArguments) {
34
+ uniqueArgsMap.set(arg.key, arg);
35
+ }
36
+ return Array.from(uniqueArgsMap.values());
37
+ }
38
+ function createZodSchemaFromArgs(args) {
39
+ const schemaObj = args.reduce((acc, placeholder) => {
40
+ acc[placeholder.key] = (0, import_n8n_workflow.generateZodSchema)(placeholder);
41
+ return acc;
42
+ }, {});
43
+ return import_zod.z.object(schemaObj).required();
44
+ }
45
+ function createToolFromNode(node, options) {
46
+ const { name, description, func, extraArgs = [] } = options;
47
+ const collectedArguments = extractFromAIParameters(node.parameters);
48
+ if (collectedArguments.length === 0 && extraArgs.length === 0) {
49
+ return new import_tools.DynamicTool({ name, description, func });
50
+ }
51
+ const allArguments = [...collectedArguments, ...extraArgs];
52
+ const schema = createZodSchemaFromArgs(allArguments);
53
+ return new import_tools.DynamicStructuredTool({ schema, name, description, func });
54
+ }
55
+ // Annotate the CommonJS export names for ESM import in node:
56
+ 0 && (module.exports = {
57
+ createToolFromNode,
58
+ createZodSchemaFromArgs,
59
+ extractFromAIParameters
60
+ });
61
+ //# sourceMappingURL=fromAIToolFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../utils/fromAIToolFactory.ts"],"sourcesContent":["import type { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';\nimport type { FromAIArgument, IDataObject, INode, INodeParameters } from 'n8n-workflow';\nimport { generateZodSchema, traverseNodeParameters } from 'n8n-workflow';\nimport { z } from 'zod';\n\nexport type ToolFunc = (\n\tquery: string | IDataObject,\n\trunManager?: CallbackManagerForToolRun,\n) => Promise<string | IDataObject | IDataObject[]>;\n\nexport interface CreateToolOptions {\n\tname: string;\n\tdescription: string;\n\tfunc: ToolFunc;\n\t/**\n\t * Extra arguments to include in the structured tool schema.\n\t * These are added after extracting $fromAI parameters from node parameters.\n\t */\n\textraArgs?: FromAIArgument[];\n}\n\n/**\n * Extracts $fromAI parameters from node parameters and returns unique arguments.\n */\nexport function extractFromAIParameters(nodeParameters: INodeParameters): FromAIArgument[] {\n\tconst collectedArguments: FromAIArgument[] = [];\n\ttraverseNodeParameters(nodeParameters, collectedArguments);\n\n\tconst uniqueArgsMap = new Map<string, FromAIArgument>();\n\tfor (const arg of collectedArguments) {\n\t\tuniqueArgsMap.set(arg.key, arg);\n\t}\n\n\treturn Array.from(uniqueArgsMap.values());\n}\n\n/**\n * Creates a Zod schema from $fromAI arguments.\n */\nexport function createZodSchemaFromArgs(args: FromAIArgument[]): z.ZodObject<z.ZodRawShape> {\n\tconst schemaObj = args.reduce((acc: Record<string, z.ZodTypeAny>, placeholder) => {\n\t\tacc[placeholder.key] = generateZodSchema(placeholder);\n\t\treturn acc;\n\t}, {});\n\n\treturn z.object(schemaObj).required();\n}\n\n/**\n * Creates a DynamicStructuredTool if node has $fromAI parameters,\n * otherwise falls back to a simple DynamicTool.\n *\n * This is useful for creating AI agent tools that can extract parameters\n * from node configuration using $fromAI expressions.\n */\nexport function createToolFromNode(\n\tnode: INode,\n\toptions: CreateToolOptions,\n): DynamicStructuredTool | DynamicTool {\n\tconst { name, description, func, extraArgs = [] } = options;\n\n\tconst collectedArguments = extractFromAIParameters(node.parameters);\n\n\t// If there are no $fromAI arguments and no extra args, fallback to simple tool\n\tif (collectedArguments.length === 0 && extraArgs.length === 0) {\n\t\treturn new DynamicTool({ name, description, func });\n\t}\n\n\t// Combine collected arguments with extra arguments\n\tconst allArguments = [...collectedArguments, ...extraArgs];\n\tconst schema = createZodSchemaFromArgs(allArguments);\n\n\treturn new DynamicStructuredTool({ schema, name, description, func });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAmD;AAEnD,0BAA0D;AAC1D,iBAAkB;AAqBX,SAAS,wBAAwB,gBAAmD;AAC1F,QAAM,qBAAuC,CAAC;AAC9C,kDAAuB,gBAAgB,kBAAkB;AAEzD,QAAM,gBAAgB,oBAAI,IAA4B;AACtD,aAAW,OAAO,oBAAoB;AACrC,kBAAc,IAAI,IAAI,KAAK,GAAG;AAAA,EAC/B;AAEA,SAAO,MAAM,KAAK,cAAc,OAAO,CAAC;AACzC;AAKO,SAAS,wBAAwB,MAAoD;AAC3F,QAAM,YAAY,KAAK,OAAO,CAAC,KAAmC,gBAAgB;AACjF,QAAI,YAAY,GAAG,QAAI,uCAAkB,WAAW;AACpD,WAAO;AAAA,EACR,GAAG,CAAC,CAAC;AAEL,SAAO,aAAE,OAAO,SAAS,EAAE,SAAS;AACrC;AASO,SAAS,mBACf,MACA,SACsC;AACtC,QAAM,EAAE,MAAM,aAAa,MAAM,YAAY,CAAC,EAAE,IAAI;AAEpD,QAAM,qBAAqB,wBAAwB,KAAK,UAAU;AAGlE,MAAI,mBAAmB,WAAW,KAAK,UAAU,WAAW,GAAG;AAC9D,WAAO,IAAI,yBAAY,EAAE,MAAM,aAAa,KAAK,CAAC;AAAA,EACnD;AAGA,QAAM,eAAe,CAAC,GAAG,oBAAoB,GAAG,SAAS;AACzD,QAAM,SAAS,wBAAwB,YAAY;AAEnD,SAAO,IAAI,mCAAsB,EAAE,QAAQ,MAAM,aAAa,KAAK,CAAC;AACrE;","names":[]}
@@ -33,7 +33,7 @@ __export(helpers_exports, {
33
33
  unwrapNestedOutput: () => unwrapNestedOutput
34
34
  });
35
35
  module.exports = __toCommonJS(helpers_exports);
36
- var import_agents = require("langchain/agents");
36
+ var import_agents = require("@langchain/classic/agents");
37
37
  var import_n8n_workflow = require("n8n-workflow");
38
38
  var import_N8nTool = require("./N8nTool");
39
39
  function hasMethods(obj, ...methodNames) {