@n8n/n8n-nodes-langchain 1.121.0 → 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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ReActAgent/execute.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { AgentExecutor, ChatAgent, ZeroShotAgent } from 'langchain/agents';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { getConnectedTools, getPromptInputByType, isChatInstance } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\nimport { throwIfToolSchema } from '@utils/schemaParsing';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { checkForStructuredTools, extractParsedOutput } from '../utils';\n\nexport async function reActAgentAgentExecute(\n\tthis: IExecuteFunctions,\n\tnodeVersion: number,\n): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing ReAct Agent');\n\n\tconst model = (await this.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0)) as\n\t\t| BaseLanguageModel\n\t\t| BaseChatModel;\n\n\tconst tools = await getConnectedTools(this, nodeVersion >= 1.5, true, true);\n\n\tawait checkForStructuredTools(tools, this.getNode(), 'ReAct Agent');\n\n\tconst outputParser = await getOptionalOutputParser(this);\n\n\tconst options = this.getNodeParameter('options', 0, {}) as {\n\t\tprefix?: string;\n\t\tsuffix?: string;\n\t\tsuffixChat?: string;\n\t\tmaxIterations?: number;\n\t\thumanMessageTemplate?: string;\n\t\treturnIntermediateSteps?: boolean;\n\t};\n\tlet agent: ChatAgent | ZeroShotAgent;\n\n\tif (isChatInstance(model)) {\n\t\tagent = ChatAgent.fromLLMAndTools(model, tools, {\n\t\t\tprefix: options.prefix,\n\t\t\tsuffix: options.suffixChat,\n\t\t\thumanMessageTemplate: options.humanMessageTemplate,\n\t\t});\n\t} else {\n\t\tagent = ZeroShotAgent.fromLLMAndTools(model, tools, {\n\t\t\tprefix: options.prefix,\n\t\t\tsuffix: options.suffix,\n\t\t});\n\t}\n\n\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\tagent,\n\t\ttools,\n\t\treturnIntermediateSteps: options?.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n\n\tconst returnData: INodeExecutionData[] = [];\n\n\tlet prompt: PromptTemplate | undefined;\n\tif (outputParser) {\n\t\tconst formatInstructions = outputParser.getFormatInstructions();\n\n\t\tprompt = new PromptTemplate({\n\t\t\ttemplate: '{input}\\n{formatInstructions}',\n\t\t\tinputVariables: ['input'],\n\t\t\tpartialVariables: { formatInstructions },\n\t\t});\n\t}\n\n\tconst items = this.getInputData();\n\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\ttry {\n\t\t\tlet input;\n\n\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\tinput = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t} else {\n\t\t\t\tinput = getPromptInputByType({\n\t\t\t\t\tctx: this,\n\t\t\t\t\ti: itemIndex,\n\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t}\n\n\t\t\tif (prompt) {\n\t\t\t\tinput = (await prompt.invoke({ input })).value;\n\t\t\t}\n\n\t\t\tconst response = await agentExecutor\n\t\t\t\t.withConfig(getTracingConfig(this))\n\t\t\t\t.invoke({ input, outputParser });\n\n\t\t\tif (outputParser) {\n\t\t\t\tresponse.output = await extractParsedOutput(this, outputParser, response.output as string);\n\t\t\t}\n\n\t\t\treturnData.push({ json: response });\n\t\t} catch (error) {\n\t\t\tthrowIfToolSchema(this, error);\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAA+B;AAC/B,oBAAwD;AACxD,0BAKO;AAEP,qBAAwE;AACxE,6BAAwC;AACxC,2BAAkC;AAClC,qBAAiC;AAEjC,mBAA6D;AAE7D,eAAsB,uBAErB,aACkC;AAClC,OAAK,OAAO,MAAM,uBAAuB;AAEzC,QAAM,QAAS,MAAM,KAAK,uBAAuB,wCAAoB,iBAAiB,CAAC;AAIvF,QAAM,QAAQ,UAAM,kCAAkB,MAAM,eAAe,KAAK,MAAM,IAAI;AAE1E,YAAM,sCAAwB,OAAO,KAAK,QAAQ,GAAG,aAAa;AAElE,QAAM,eAAe,UAAM,gDAAwB,IAAI;AAEvD,QAAM,UAAU,KAAK,iBAAiB,WAAW,GAAG,CAAC,CAAC;AAQtD,MAAI;AAEJ,UAAI,+BAAe,KAAK,GAAG;AAC1B,YAAQ,wBAAU,gBAAgB,OAAO,OAAO;AAAA,MAC/C,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,sBAAsB,QAAQ;AAAA,IAC/B,CAAC;AAAA,EACF,OAAO;AACN,YAAQ,4BAAc,gBAAgB,OAAO,OAAO;AAAA,MACnD,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IACjB,CAAC;AAAA,EACF;AAEA,QAAM,gBAAgB,4BAAc,kBAAkB;AAAA,IACrD;AAAA,IACA;AAAA,IACA,yBAAyB,SAAS,4BAA4B;AAAA,IAC9D,eAAe,QAAQ,iBAAiB;AAAA,EACzC,CAAC;AAED,QAAM,aAAmC,CAAC;AAE1C,MAAI;AACJ,MAAI,cAAc;AACjB,UAAM,qBAAqB,aAAa,sBAAsB;AAE9D,aAAS,IAAI,8BAAe;AAAA,MAC3B,UAAU;AAAA,MACV,gBAAgB,CAAC,OAAO;AAAA,MACxB,kBAAkB,EAAE,mBAAmB;AAAA,IACxC,CAAC;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK,aAAa;AAChC,WAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,QAAI;AACH,UAAI;AAEJ,UAAI,KAAK,QAAQ,EAAE,eAAe,KAAK;AACtC,gBAAQ,KAAK,iBAAiB,QAAQ,SAAS;AAAA,MAChD,OAAO;AACN,oBAAQ,qCAAqB;AAAA,UAC5B,KAAK;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,UACV,eAAe;AAAA,QAChB,CAAC;AAAA,MACF;AAEA,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAAgC;AAAA,MAC9E;AAEA,UAAI,QAAQ;AACX,iBAAS,MAAM,OAAO,OAAO,EAAE,MAAM,CAAC,GAAG;AAAA,MAC1C;AAEA,YAAM,WAAW,MAAM,cACrB,eAAW,iCAAiB,IAAI,CAAC,EACjC,OAAO,EAAE,OAAO,aAAa,CAAC;AAEhC,UAAI,cAAc;AACjB,iBAAS,SAAS,UAAM,kCAAoB,MAAM,cAAc,SAAS,MAAgB;AAAA,MAC1F;AAEA,iBAAW,KAAK,EAAE,MAAM,SAAS,CAAC;AAAA,IACnC,SAAS,OAAO;AACf,kDAAkB,MAAM,KAAK;AAC7B,UAAI,KAAK,eAAe,GAAG;AAC1B,mBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,MAAM,QAAQ,GAAG,YAAY,EAAE,MAAM,UAAU,EAAE,CAAC;AACnF;AAAA,MACD;AAEA,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":[]}
1
+ {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ReActAgent/execute.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport { AgentExecutor, ChatAgent, ZeroShotAgent } from '@langchain/classic/agents';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { getConnectedTools, getPromptInputByType, isChatInstance } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\nimport { throwIfToolSchema } from '@utils/schemaParsing';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { checkForStructuredTools, extractParsedOutput } from '../utils';\n\nexport async function reActAgentAgentExecute(\n\tthis: IExecuteFunctions,\n\tnodeVersion: number,\n): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing ReAct Agent');\n\n\tconst model = (await this.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0)) as\n\t\t| BaseLanguageModel\n\t\t| BaseChatModel;\n\n\tconst tools = await getConnectedTools(this, nodeVersion >= 1.5, true, true);\n\n\tawait checkForStructuredTools(tools, this.getNode(), 'ReAct Agent');\n\n\tconst outputParser = await getOptionalOutputParser(this);\n\n\tconst options = this.getNodeParameter('options', 0, {}) as {\n\t\tprefix?: string;\n\t\tsuffix?: string;\n\t\tsuffixChat?: string;\n\t\tmaxIterations?: number;\n\t\thumanMessageTemplate?: string;\n\t\treturnIntermediateSteps?: boolean;\n\t};\n\tlet agent: ChatAgent | ZeroShotAgent;\n\n\tif (isChatInstance(model)) {\n\t\tagent = ChatAgent.fromLLMAndTools(model, tools, {\n\t\t\tprefix: options.prefix,\n\t\t\tsuffix: options.suffixChat,\n\t\t\thumanMessageTemplate: options.humanMessageTemplate,\n\t\t});\n\t} else {\n\t\tagent = ZeroShotAgent.fromLLMAndTools(model, tools, {\n\t\t\tprefix: options.prefix,\n\t\t\tsuffix: options.suffix,\n\t\t});\n\t}\n\n\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\tagent,\n\t\ttools,\n\t\treturnIntermediateSteps: options?.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n\n\tconst returnData: INodeExecutionData[] = [];\n\n\tlet prompt: PromptTemplate | undefined;\n\tif (outputParser) {\n\t\tconst formatInstructions = outputParser.getFormatInstructions();\n\n\t\tprompt = new PromptTemplate({\n\t\t\ttemplate: '{input}\\n{formatInstructions}',\n\t\t\tinputVariables: ['input'],\n\t\t\tpartialVariables: { formatInstructions },\n\t\t});\n\t}\n\n\tconst items = this.getInputData();\n\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\ttry {\n\t\t\tlet input;\n\n\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\tinput = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t} else {\n\t\t\t\tinput = getPromptInputByType({\n\t\t\t\t\tctx: this,\n\t\t\t\t\ti: itemIndex,\n\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t}\n\n\t\t\tif (prompt) {\n\t\t\t\tinput = (await prompt.invoke({ input })).value;\n\t\t\t}\n\n\t\t\tconst response = await agentExecutor\n\t\t\t\t.withConfig(getTracingConfig(this))\n\t\t\t\t.invoke({ input, outputParser });\n\n\t\t\tif (outputParser) {\n\t\t\t\tresponse.output = await extractParsedOutput(this, outputParser, response.output as string);\n\t\t\t}\n\n\t\t\treturnData.push({ json: response });\n\t\t} catch (error) {\n\t\t\tthrowIfToolSchema(this, error);\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAA+B;AAC/B,oBAAwD;AACxD,0BAKO;AAEP,qBAAwE;AACxE,6BAAwC;AACxC,2BAAkC;AAClC,qBAAiC;AAEjC,mBAA6D;AAE7D,eAAsB,uBAErB,aACkC;AAClC,OAAK,OAAO,MAAM,uBAAuB;AAEzC,QAAM,QAAS,MAAM,KAAK,uBAAuB,wCAAoB,iBAAiB,CAAC;AAIvF,QAAM,QAAQ,UAAM,kCAAkB,MAAM,eAAe,KAAK,MAAM,IAAI;AAE1E,YAAM,sCAAwB,OAAO,KAAK,QAAQ,GAAG,aAAa;AAElE,QAAM,eAAe,UAAM,gDAAwB,IAAI;AAEvD,QAAM,UAAU,KAAK,iBAAiB,WAAW,GAAG,CAAC,CAAC;AAQtD,MAAI;AAEJ,UAAI,+BAAe,KAAK,GAAG;AAC1B,YAAQ,wBAAU,gBAAgB,OAAO,OAAO;AAAA,MAC/C,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,sBAAsB,QAAQ;AAAA,IAC/B,CAAC;AAAA,EACF,OAAO;AACN,YAAQ,4BAAc,gBAAgB,OAAO,OAAO;AAAA,MACnD,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IACjB,CAAC;AAAA,EACF;AAEA,QAAM,gBAAgB,4BAAc,kBAAkB;AAAA,IACrD;AAAA,IACA;AAAA,IACA,yBAAyB,SAAS,4BAA4B;AAAA,IAC9D,eAAe,QAAQ,iBAAiB;AAAA,EACzC,CAAC;AAED,QAAM,aAAmC,CAAC;AAE1C,MAAI;AACJ,MAAI,cAAc;AACjB,UAAM,qBAAqB,aAAa,sBAAsB;AAE9D,aAAS,IAAI,8BAAe;AAAA,MAC3B,UAAU;AAAA,MACV,gBAAgB,CAAC,OAAO;AAAA,MACxB,kBAAkB,EAAE,mBAAmB;AAAA,IACxC,CAAC;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK,aAAa;AAChC,WAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,QAAI;AACH,UAAI;AAEJ,UAAI,KAAK,QAAQ,EAAE,eAAe,KAAK;AACtC,gBAAQ,KAAK,iBAAiB,QAAQ,SAAS;AAAA,MAChD,OAAO;AACN,oBAAQ,qCAAqB;AAAA,UAC5B,KAAK;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,UACV,eAAe;AAAA,QAChB,CAAC;AAAA,MACF;AAEA,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAAgC;AAAA,MAC9E;AAEA,UAAI,QAAQ;AACX,iBAAS,MAAM,OAAO,OAAO,EAAE,MAAM,CAAC,GAAG;AAAA,MAC1C;AAEA,YAAM,WAAW,MAAM,cACrB,eAAW,iCAAiB,IAAI,CAAC,EACjC,OAAO,EAAE,OAAO,aAAa,CAAC;AAEhC,UAAI,cAAc;AACjB,iBAAS,SAAS,UAAM,kCAAoB,MAAM,cAAc,SAAS,MAAgB;AAAA,MAC1F;AAEA,iBAAW,KAAK,EAAE,MAAM,SAAS,CAAC;AAAA,IACnC,SAAS,OAAO;AACf,kDAAkB,MAAM,KAAK;AAC7B,UAAI,KAAK,eAAe,GAAG;AAC1B,mBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,MAAM,QAAQ,GAAG,YAAY,EAAE,MAAM,UAAU,EAAE,CAAC;AACnF;AAAA,MACD;AAEA,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":[]}
@@ -21,8 +21,8 @@ __export(execute_exports, {
21
21
  sqlAgentAgentExecute: () => sqlAgentAgentExecute
22
22
  });
23
23
  module.exports = __toCommonJS(execute_exports);
24
- var import_sql = require("langchain/agents/toolkits/sql");
25
- var import_sql_db = require("langchain/sql_db");
24
+ var import_sql = require("@langchain/classic/agents/toolkits/sql");
25
+ var import_sql_db = require("@langchain/classic/sql_db");
26
26
  var import_n8n_workflow = require("n8n-workflow");
27
27
  var import_helpers = require("../../../../../utils/helpers");
28
28
  var import_tracing = require("../../../../../utils/tracing");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/SqlAgent/execute.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { DataSource } from '@n8n/typeorm';\nimport type { SqlCreatePromptArgs } from 'langchain/agents/toolkits/sql';\nimport { SqlToolkit, createSqlAgent } from 'langchain/agents/toolkits/sql';\nimport { SqlDatabase } from 'langchain/sql_db';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype IDataObject,\n} from 'n8n-workflow';\n\nimport { getPromptInputByType, serializeChatHistory } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { getMysqlDataSource } from './other/handlers/mysql';\nimport { getPostgresDataSource } from './other/handlers/postgres';\nimport { getSqliteDataSource } from './other/handlers/sqlite';\nimport { SQL_PREFIX, SQL_SUFFIX } from './other/prompts';\n\nconst parseTablesString = (tablesString: string) =>\n\ttablesString\n\t\t.split(',')\n\t\t.map((table) => table.trim())\n\t\t.filter((table) => table.length > 0);\n\nexport async function sqlAgentAgentExecute(\n\tthis: IExecuteFunctions,\n): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing SQL Agent');\n\n\tconst model = (await this.getInputConnectionData(\n\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t0,\n\t)) as BaseLanguageModel;\n\tconst items = this.getInputData();\n\n\tconst returnData: INodeExecutionData[] = [];\n\n\tfor (let i = 0; i < items.length; i++) {\n\t\ttry {\n\t\t\tconst item = items[i];\n\t\t\tlet input;\n\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\tinput = this.getNodeParameter('input', i) as string;\n\t\t\t} else {\n\t\t\t\tinput = getPromptInputByType({\n\t\t\t\t\tctx: this,\n\t\t\t\t\ti,\n\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘prompt’ parameter is empty.');\n\t\t\t}\n\n\t\t\tconst options = this.getNodeParameter('options', i, {});\n\t\t\tconst selectedDataSource = this.getNodeParameter('dataSource', i, 'sqlite') as\n\t\t\t\t| 'mysql'\n\t\t\t\t| 'postgres'\n\t\t\t\t| 'sqlite';\n\n\t\t\tconst includedSampleRows = options.includedSampleRows as number;\n\t\t\tconst includedTablesArray = parseTablesString((options.includedTables as string) ?? '');\n\t\t\tconst ignoredTablesArray = parseTablesString((options.ignoredTables as string) ?? '');\n\n\t\t\tlet dataSource: DataSource | null = null;\n\t\t\tif (selectedDataSource === 'sqlite') {\n\t\t\t\tif (!item.binary) {\n\t\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\t'No binary data found, please connect a binary to the input if you want to use SQLite as data source',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst binaryPropertyName = this.getNodeParameter('binaryPropertyName', i, 'data');\n\t\t\t\tdataSource = await getSqliteDataSource.call(this, item.binary, binaryPropertyName);\n\t\t\t}\n\n\t\t\tif (selectedDataSource === 'postgres') {\n\t\t\t\tdataSource = await getPostgresDataSource.call(this);\n\t\t\t}\n\n\t\t\tif (selectedDataSource === 'mysql') {\n\t\t\t\tdataSource = await getMysqlDataSource.call(this);\n\t\t\t}\n\n\t\t\tif (!dataSource) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t'No data source found, please configure data source',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst agentOptions: SqlCreatePromptArgs = {\n\t\t\t\ttopK: (options.topK as number) ?? 10,\n\t\t\t\tprefix: (options.prefixPrompt as string) ?? SQL_PREFIX,\n\t\t\t\tsuffix: (options.suffixPrompt as string) ?? SQL_SUFFIX,\n\t\t\t\tinputVariables: ['chatHistory', 'input', 'agent_scratchpad'],\n\t\t\t};\n\n\t\t\tconst dbInstance = await SqlDatabase.fromDataSourceParams({\n\t\t\t\tappDataSource: dataSource,\n\t\t\t\tincludesTables: includedTablesArray.length > 0 ? includedTablesArray : undefined,\n\t\t\t\tignoreTables: ignoredTablesArray.length > 0 ? ignoredTablesArray : undefined,\n\t\t\t\tsampleRowsInTableInfo: includedSampleRows ?? 3,\n\t\t\t});\n\n\t\t\tconst toolkit = new SqlToolkit(dbInstance, model);\n\t\t\tconst agentExecutor = createSqlAgent(model, toolkit, agentOptions);\n\n\t\t\tconst memory = (await this.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t| BaseChatMemory\n\t\t\t\t| undefined;\n\n\t\t\tagentExecutor.memory = memory;\n\n\t\t\tlet chatHistory = '';\n\t\t\tif (memory) {\n\t\t\t\tconst messages = await memory.chatHistory.getMessages();\n\t\t\t\tchatHistory = serializeChatHistory(messages);\n\t\t\t}\n\n\t\t\tlet response: IDataObject;\n\t\t\ttry {\n\t\t\t\tresponse = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tinput,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\tchatHistory,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif ((error.message as IDataObject)?.output) {\n\t\t\t\t\tresponse = error.message as IDataObject;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message as string, { itemIndex: i });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturnData.push({ json: response });\n\t\t} catch (error) {\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: i } });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/SqlAgent/execute.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { DataSource } from '@n8n/typeorm';\nimport type { SqlCreatePromptArgs } from '@langchain/classic/agents/toolkits/sql';\nimport { SqlToolkit, createSqlAgent } from '@langchain/classic/agents/toolkits/sql';\nimport { SqlDatabase } from '@langchain/classic/sql_db';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype IDataObject,\n} from 'n8n-workflow';\n\nimport { getPromptInputByType, serializeChatHistory } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { getMysqlDataSource } from './other/handlers/mysql';\nimport { getPostgresDataSource } from './other/handlers/postgres';\nimport { getSqliteDataSource } from './other/handlers/sqlite';\nimport { SQL_PREFIX, SQL_SUFFIX } from './other/prompts';\n\nconst parseTablesString = (tablesString: string) =>\n\ttablesString\n\t\t.split(',')\n\t\t.map((table) => table.trim())\n\t\t.filter((table) => table.length > 0);\n\nexport async function sqlAgentAgentExecute(\n\tthis: IExecuteFunctions,\n): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing SQL Agent');\n\n\tconst model = (await this.getInputConnectionData(\n\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t0,\n\t)) as BaseLanguageModel;\n\tconst items = this.getInputData();\n\n\tconst returnData: INodeExecutionData[] = [];\n\n\tfor (let i = 0; i < items.length; i++) {\n\t\ttry {\n\t\t\tconst item = items[i];\n\t\t\tlet input;\n\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\tinput = this.getNodeParameter('input', i) as string;\n\t\t\t} else {\n\t\t\t\tinput = getPromptInputByType({\n\t\t\t\t\tctx: this,\n\t\t\t\t\ti,\n\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘prompt’ parameter is empty.');\n\t\t\t}\n\n\t\t\tconst options = this.getNodeParameter('options', i, {});\n\t\t\tconst selectedDataSource = this.getNodeParameter('dataSource', i, 'sqlite') as\n\t\t\t\t| 'mysql'\n\t\t\t\t| 'postgres'\n\t\t\t\t| 'sqlite';\n\n\t\t\tconst includedSampleRows = options.includedSampleRows as number;\n\t\t\tconst includedTablesArray = parseTablesString((options.includedTables as string) ?? '');\n\t\t\tconst ignoredTablesArray = parseTablesString((options.ignoredTables as string) ?? '');\n\n\t\t\tlet dataSource: DataSource | null = null;\n\t\t\tif (selectedDataSource === 'sqlite') {\n\t\t\t\tif (!item.binary) {\n\t\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\t'No binary data found, please connect a binary to the input if you want to use SQLite as data source',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst binaryPropertyName = this.getNodeParameter('binaryPropertyName', i, 'data');\n\t\t\t\tdataSource = await getSqliteDataSource.call(this, item.binary, binaryPropertyName);\n\t\t\t}\n\n\t\t\tif (selectedDataSource === 'postgres') {\n\t\t\t\tdataSource = await getPostgresDataSource.call(this);\n\t\t\t}\n\n\t\t\tif (selectedDataSource === 'mysql') {\n\t\t\t\tdataSource = await getMysqlDataSource.call(this);\n\t\t\t}\n\n\t\t\tif (!dataSource) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t'No data source found, please configure data source',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst agentOptions: SqlCreatePromptArgs = {\n\t\t\t\ttopK: (options.topK as number) ?? 10,\n\t\t\t\tprefix: (options.prefixPrompt as string) ?? SQL_PREFIX,\n\t\t\t\tsuffix: (options.suffixPrompt as string) ?? SQL_SUFFIX,\n\t\t\t\tinputVariables: ['chatHistory', 'input', 'agent_scratchpad'],\n\t\t\t};\n\n\t\t\tconst dbInstance = await SqlDatabase.fromDataSourceParams({\n\t\t\t\tappDataSource: dataSource,\n\t\t\t\tincludesTables: includedTablesArray.length > 0 ? includedTablesArray : undefined,\n\t\t\t\tignoreTables: ignoredTablesArray.length > 0 ? ignoredTablesArray : undefined,\n\t\t\t\tsampleRowsInTableInfo: includedSampleRows ?? 3,\n\t\t\t});\n\n\t\t\tconst toolkit = new SqlToolkit(dbInstance, model);\n\t\t\tconst agentExecutor = createSqlAgent(model, toolkit, agentOptions);\n\n\t\t\tconst memory = (await this.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t| BaseChatMemory\n\t\t\t\t| undefined;\n\n\t\t\tagentExecutor.memory = memory;\n\n\t\t\tlet chatHistory = '';\n\t\t\tif (memory) {\n\t\t\t\tconst messages = await memory.chatHistory.getMessages();\n\t\t\t\tchatHistory = serializeChatHistory(messages);\n\t\t\t}\n\n\t\t\tlet response: IDataObject;\n\t\t\ttry {\n\t\t\t\tresponse = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tinput,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\tchatHistory,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif ((error.message as IDataObject)?.output) {\n\t\t\t\t\tresponse = error.message as IDataObject;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message as string, { itemIndex: i });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturnData.push({ json: response });\n\t\t} catch (error) {\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: i } });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":"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","names":[]}
@@ -32,7 +32,7 @@ __export(execute_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(execute_exports);
34
34
  var import_runnables = require("@langchain/core/runnables");
35
- var import_agents = require("langchain/agents");
35
+ var import_agents = require("@langchain/classic/agents");
36
36
  var import_omit = __toESM(require("lodash/omit"));
37
37
  var import_n8n_workflow = require("n8n-workflow");
38
38
  var import_helpers = require("../../../../../../utils/helpers");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V1/execute.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport { AgentExecutor, createToolCallingAgent } from 'langchain/agents';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing Tools Agent');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst outputParser = await getOptionalOutputParser(this);\n\tconst tools = await getTools(this, outputParser);\n\n\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\ttry {\n\t\t\tconst model = (await getChatModel(this)) as BaseLanguageModel;\n\t\t\tconst memory = await getOptionalMemory(this);\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The “text” parameter is empty.');\n\t\t\t}\n\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt = preparePrompt(messages);\n\n\t\t\t// Create the base agent that calls tools.\n\t\t\tconst agent = createToolCallingAgent({\n\t\t\t\tllm: model,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\tstreamRunnable: false,\n\t\t\t});\n\t\t\tagent.streamRunnable = false;\n\t\t\t// Wrap the agent with parsers and fixes.\n\t\t\tconst runnableAgent = RunnableSequence.from([\n\t\t\t\tagent,\n\t\t\t\tgetAgentStepsParser(outputParser, memory),\n\t\t\t\tfixEmptyContentMessage,\n\t\t\t]);\n\t\t\tconst executor = AgentExecutor.fromAgentAndTools({\n\t\t\t\tagent: runnableAgent,\n\t\t\t\tmemory,\n\t\t\t\ttools,\n\t\t\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\t\t\tmaxIterations: options.maxIterations ?? 10,\n\t\t\t});\n\n\t\t\t// Invoke the executor with the given input and system message.\n\t\t\tconst response = await executor.invoke(\n\t\t\t\t{\n\t\t\t\t\tinput,\n\t\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\t\tformatting_instructions:\n\t\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t\t},\n\t\t\t\t{ signal: this.getExecutionCancelSignal() },\n\t\t\t);\n\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t} catch (error) {\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAiC;AACjC,oBAAsD;AACtD,kBAAiB;AACjB,0BAA8C;AAG9C,qBAAqC;AACrC,6BAAwC;AAExC,oBAQO;AACP,oBAA+B;AAc/B,eAAsB,oBAA4E;AACjG,OAAK,OAAO,MAAM,uBAAuB;AAEzC,QAAM,aAAmC,CAAC;AAC1C,QAAM,QAAQ,KAAK,aAAa;AAChC,QAAM,eAAe,UAAM,gDAAwB,IAAI;AACvD,QAAM,QAAQ,UAAM,wBAAS,MAAM,YAAY;AAE/C,WAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,QAAI;AACH,YAAM,QAAS,UAAM,4BAAa,IAAI;AACtC,YAAM,SAAS,UAAM,iCAAkB,IAAI;AAE3C,YAAM,YAAQ,qCAAqB;AAAA,QAClC,KAAK;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,eAAe;AAAA,MAChB,CAAC;AACD,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAAgC;AAAA,MAC9E;AAEA,YAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAQ9D,YAAM,WAAW,UAAM,+BAAgB,MAAM,WAAW;AAAA,QACvD,eAAe,QAAQ;AAAA,QACvB,yBAAyB,QAAQ,2BAA2B;AAAA,QAC5D;AAAA,MACD,CAAC;AACD,YAAM,aAAS,6BAAc,QAAQ;AAGrC,YAAM,YAAQ,sCAAuB;AAAA,QACpC,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,MACjB,CAAC;AACD,YAAM,iBAAiB;AAEvB,YAAM,gBAAgB,kCAAiB,KAAK;AAAA,QAC3C;AAAA,YACA,mCAAoB,cAAc,MAAM;AAAA,QACxC;AAAA,MACD,CAAC;AACD,YAAM,WAAW,4BAAc,kBAAkB;AAAA,QAChD,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,yBAAyB,QAAQ,4BAA4B;AAAA,QAC7D,eAAe,QAAQ,iBAAiB;AAAA,MACzC,CAAC;AAGD,YAAM,WAAW,MAAM,SAAS;AAAA,QAC/B;AAAA,UACC;AAAA,UACA,gBAAgB,QAAQ,iBAAiB;AAAA,UACzC,yBACC;AAAA,QACF;AAAA,QACA,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAAA,MAC3C;AAGA,UAAI,UAAU,cAAc;AAC3B,cAAM,mBAAe;AAAA,UACpB,SAAS;AAAA,QACV;AACA,iBAAS,SAAS,cAAc,UAAU;AAAA,MAC3C;AAGA,YAAM,aAAa;AAAA,QAClB,UAAM,YAAAA;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAEA,iBAAW,KAAK,UAAU;AAAA,IAC3B,SAAS,OAAO;AACf,UAAI,KAAK,eAAe,GAAG;AAC1B,mBAAW,KAAK;AAAA,UACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,UAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,QAC/B,CAAC;AACD;AAAA,MACD;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":["omit"]}
1
+ {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V1/execute.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport { AgentExecutor, createToolCallingAgent } from '@langchain/classic/agents';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\tthis.logger.debug('Executing Tools Agent');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst outputParser = await getOptionalOutputParser(this);\n\tconst tools = await getTools(this, outputParser);\n\n\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\ttry {\n\t\t\tconst model = (await getChatModel(this)) as BaseLanguageModel;\n\t\t\tconst memory = await getOptionalMemory(this);\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The “text” parameter is empty.');\n\t\t\t}\n\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt = preparePrompt(messages);\n\n\t\t\t// Create the base agent that calls tools.\n\t\t\tconst agent = createToolCallingAgent({\n\t\t\t\tllm: model,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\tstreamRunnable: false,\n\t\t\t});\n\t\t\tagent.streamRunnable = false;\n\t\t\t// Wrap the agent with parsers and fixes.\n\t\t\tconst runnableAgent = RunnableSequence.from([\n\t\t\t\tagent,\n\t\t\t\tgetAgentStepsParser(outputParser, memory),\n\t\t\t\tfixEmptyContentMessage,\n\t\t\t]);\n\t\t\tconst executor = AgentExecutor.fromAgentAndTools({\n\t\t\t\tagent: runnableAgent,\n\t\t\t\tmemory,\n\t\t\t\ttools,\n\t\t\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\t\t\tmaxIterations: options.maxIterations ?? 10,\n\t\t\t});\n\n\t\t\t// Invoke the executor with the given input and system message.\n\t\t\tconst response = await executor.invoke(\n\t\t\t\t{\n\t\t\t\t\tinput,\n\t\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\t\tformatting_instructions:\n\t\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t\t},\n\t\t\t\t{ signal: this.getExecutionCancelSignal() },\n\t\t\t);\n\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t} catch (error) {\n\t\t\tif (this.continueOnFail()) {\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAiC;AACjC,oBAAsD;AACtD,kBAAiB;AACjB,0BAA8C;AAG9C,qBAAqC;AACrC,6BAAwC;AAExC,oBAQO;AACP,oBAA+B;AAc/B,eAAsB,oBAA4E;AACjG,OAAK,OAAO,MAAM,uBAAuB;AAEzC,QAAM,aAAmC,CAAC;AAC1C,QAAM,QAAQ,KAAK,aAAa;AAChC,QAAM,eAAe,UAAM,gDAAwB,IAAI;AACvD,QAAM,QAAQ,UAAM,wBAAS,MAAM,YAAY;AAE/C,WAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,QAAI;AACH,YAAM,QAAS,UAAM,4BAAa,IAAI;AACtC,YAAM,SAAS,UAAM,iCAAkB,IAAI;AAE3C,YAAM,YAAQ,qCAAqB;AAAA,QAClC,KAAK;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,eAAe;AAAA,MAChB,CAAC;AACD,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAAgC;AAAA,MAC9E;AAEA,YAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAQ9D,YAAM,WAAW,UAAM,+BAAgB,MAAM,WAAW;AAAA,QACvD,eAAe,QAAQ;AAAA,QACvB,yBAAyB,QAAQ,2BAA2B;AAAA,QAC5D;AAAA,MACD,CAAC;AACD,YAAM,aAAS,6BAAc,QAAQ;AAGrC,YAAM,YAAQ,sCAAuB;AAAA,QACpC,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,MACjB,CAAC;AACD,YAAM,iBAAiB;AAEvB,YAAM,gBAAgB,kCAAiB,KAAK;AAAA,QAC3C;AAAA,YACA,mCAAoB,cAAc,MAAM;AAAA,QACxC;AAAA,MACD,CAAC;AACD,YAAM,WAAW,4BAAc,kBAAkB;AAAA,QAChD,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,yBAAyB,QAAQ,4BAA4B;AAAA,QAC7D,eAAe,QAAQ,iBAAiB;AAAA,MACzC,CAAC;AAGD,YAAM,WAAW,MAAM,SAAS;AAAA,QAC/B;AAAA,UACC;AAAA,UACA,gBAAgB,QAAQ,iBAAiB;AAAA,UACzC,yBACC;AAAA,QACF;AAAA,QACA,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAAA,MAC3C;AAGA,UAAI,UAAU,cAAc;AAC3B,cAAM,mBAAe;AAAA,UACpB,SAAS;AAAA,QACV;AACA,iBAAS,SAAS,cAAc,UAAU;AAAA,MAC3C;AAGA,YAAM,aAAa;AAAA,QAClB,UAAM,YAAAA;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAEA,iBAAW,KAAK,UAAU;AAAA,IAC3B,SAAS,OAAO;AACf,UAAI,KAAK,eAAe,GAAG;AAC1B,mBAAW,KAAK;AAAA,UACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,UAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,QAC/B,CAAC;AACD;AAAA,MACD;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":["omit"]}
@@ -32,7 +32,7 @@ __export(execute_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(execute_exports);
34
34
  var import_runnables = require("@langchain/core/runnables");
35
- var import_agents = require("langchain/agents");
35
+ var import_agents = require("@langchain/classic/agents");
36
36
  var import_omit = __toESM(require("lodash/omit"));
37
37
  var import_n8n_workflow = require("n8n-workflow");
38
38
  var import_node_assert = __toESM(require("node:assert"));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V2/execute.ts"],"sourcesContent":["import type { StreamEvent } from '@langchain/core/dist/tracers/event_stream';\nimport type { IterableReadableStream } from '@langchain/core/dist/utils/stream';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AIMessageChunk, MessageContentText } from '@langchain/core/messages';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport {\n\tAgentExecutor,\n\ttype AgentRunnableSequence,\n\tcreateToolCallingAgent,\n} from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError, sleep } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData, ISupplyDataFunctions } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\nimport { ChatOpenAI } from '@langchain/openai';\n\n/**\n * Creates an agent executor with the given configuration\n */\nfunction createAgentExecutor(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\toptions: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools,\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]) as AgentRunnableSequence;\n\n\trunnableAgent.singleAction = false;\n\trunnableAgent.streamRunnable = false;\n\n\treturn AgentExecutor.fromAgentAndTools({\n\t\tagent: runnableAgent,\n\t\tmemory,\n\t\ttools,\n\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n}\n\nasync function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n\treturnIntermediateSteps: boolean = false,\n): Promise<{ output: string; intermediateSteps?: any[] }> {\n\tconst agentResult: { output: string; intermediateSteps?: any[] } = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tctx.sendChunk('begin', 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 (returnIntermediateSteps && event.data) {\n\t\t\t\t\tconst chatModelData = event.data as any;\n\t\t\t\t\tconst output = chatModelData.output;\n\n\t\t\t\t\t// Check if this LLM response contains tool calls\n\t\t\t\t\tif (output?.tool_calls && output.tool_calls.length > 0) {\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\tagentResult.intermediateSteps!.push({\n\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\t\ttype: toolCall.type,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_tool_end':\n\t\t\t\t// Capture tool execution results and match with action\n\t\t\t\tif (returnIntermediateSteps && event.data && agentResult.intermediateSteps!.length > 0) {\n\t\t\t\t\tconst toolData = event.data as any;\n\t\t\t\t\t// Find the matching intermediate step for this tool call\n\t\t\t\t\tconst matchingStep = agentResult.intermediateSteps!.find(\n\t\t\t\t\t\t(step) => !step.observation && step.action.tool === event.name,\n\t\t\t\t\t);\n\t\t\t\t\tif (matchingStep) {\n\t\t\t\t\t\tmatchingStep.observation = toolData.output;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\treturn agentResult;\n}\n\nfunction checkIsResponsesApi(model: BaseChatModel | null | undefined): boolean {\n\ttry {\n\t\tconst isUsingResponsesApi =\n\t\t\t!!model && model instanceof ChatOpenAI && 'useResponsesApi' in model && model.useResponsesApi;\n\t\treturn isUsingResponsesApi;\n\t} catch (error) {\n\t\treturn false;\n\t}\n}\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @param this Execute context. SupplyDataContext is passed when agent is as a tool\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(\n\tthis: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<INodeExecutionData[][]> {\n\tconst version = this.getNode().typeVersion;\n\tthis.logger.debug('Executing Tools Agent V2');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\t// FIXME: remove when this is fixed: https://github.com/langchain-ai/langchainjs/pull/9082\n\t// Responses API + tools is broken when using langchain default call handling. In V3 calls are handled differently, so it works.\n\tif (checkIsResponsesApi(model)) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t`This model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`,\n\t\t);\n\t}\n\n\tif (checkIsResponsesApi(fallbackModel)) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t`This fallback model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`,\n\t\t);\n\t}\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\t// Check if streaming is enabled\n\tconst enableStreaming = this.getNodeParameter('options.enableStreaming', 0, true) as boolean;\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The \"text\" parameter is empty.');\n\t\t\t}\n\t\t\tconst outputParser = await getOptionalOutputParser(this, itemIndex);\n\t\t\tconst tools = await getTools(this, outputParser);\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\t\t\t// Create executors for primary and fallback models\n\t\t\tconst executor = createAgentExecutor(\n\t\t\t\tmodel,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\toptions,\n\t\t\t\toutputParser,\n\t\t\t\tmemory,\n\t\t\t\tfallbackModel,\n\t\t\t);\n\t\t\t// Invoke with fallback logic\n\t\t\tconst invokeParams = {\n\t\t\t\tinput,\n\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\tformatting_instructions:\n\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t};\n\t\t\tconst executeOptions = { signal: this.getExecutionCancelSignal() };\n\n\t\t\t// Check if streaming is actually available\n\t\t\tconst isStreamingAvailable = 'isStreaming' in this ? this.isStreaming?.() : undefined;\n\n\t\t\tif (\n\t\t\t\t'isStreaming' in this &&\n\t\t\t\tenableStreaming &&\n\t\t\t\tisStreamingAvailable &&\n\t\t\t\tthis.getNode().typeVersion >= 2.1\n\t\t\t) {\n\t\t\t\t// Get chat history respecting the context window length configured in memory\n\t\t\t\tlet chatHistory;\n\t\t\t\tif (memory) {\n\t\t\t\t\t// Load memory variables to respect context window length\n\t\t\t\t\tconst memoryVariables = await memory.loadMemoryVariables({});\n\t\t\t\t\tchatHistory = memoryVariables['chat_history'];\n\t\t\t\t}\n\t\t\t\tconst eventStream = executor.streamEvents(\n\t\t\t\t\t{\n\t\t\t\t\t\t...invokeParams,\n\t\t\t\t\t\tchat_history: chatHistory ?? undefined,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tversion: 'v2',\n\t\t\t\t\t\t...executeOptions,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn await processEventStream(\n\t\t\t\t\tthis,\n\t\t\t\t\teventStream,\n\t\t\t\t\titemIndex,\n\t\t\t\t\toptions.returnIntermediateSteps,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle regular execution\n\t\t\t\treturn await executor.invoke(invokeParams, executeOptions);\n\t\t\t}\n\t\t});\n\n\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\t\t// This is only used to check if the output parser is connected\n\t\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\t\tconst outputParser = await getOptionalOutputParser(this, 0);\n\t\tbatchResults.forEach((result, index) => {\n\t\t\tconst itemIndex = i + index;\n\t\t\tif (result.status === 'rejected') {\n\t\t\t\tconst error = result.reason as Error;\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst response = result.value;\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t});\n\n\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\tawait sleep(delayBetweenBatches);\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":"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","names":["assert","outputParser","omit"]}
1
+ {"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V2/execute.ts"],"sourcesContent":["import type { StreamEvent } from '@langchain/core/dist/tracers/event_stream';\nimport type { IterableReadableStream } from '@langchain/core/dist/utils/stream';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AIMessageChunk, MessageContentText } from '@langchain/core/messages';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport {\n\tAgentExecutor,\n\ttype AgentRunnableSequence,\n\tcreateToolCallingAgent,\n} from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport type { DynamicStructuredTool, Tool } from '@langchain/classic/tools';\nimport omit from 'lodash/omit';\nimport { jsonParse, NodeOperationError, sleep } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeExecutionData, ISupplyDataFunctions } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\nimport { ChatOpenAI } from '@langchain/openai';\n\n/**\n * Creates an agent executor with the given configuration\n */\nfunction createAgentExecutor(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\toptions: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools,\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]) as AgentRunnableSequence;\n\n\trunnableAgent.singleAction = false;\n\trunnableAgent.streamRunnable = false;\n\n\treturn AgentExecutor.fromAgentAndTools({\n\t\tagent: runnableAgent,\n\t\tmemory,\n\t\ttools,\n\t\treturnIntermediateSteps: options.returnIntermediateSteps === true,\n\t\tmaxIterations: options.maxIterations ?? 10,\n\t});\n}\n\nasync function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n\treturnIntermediateSteps: boolean = false,\n): Promise<{ output: string; intermediateSteps?: any[] }> {\n\tconst agentResult: { output: string; intermediateSteps?: any[] } = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tctx.sendChunk('begin', 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 (returnIntermediateSteps && event.data) {\n\t\t\t\t\tconst chatModelData = event.data as any;\n\t\t\t\t\tconst output = chatModelData.output;\n\n\t\t\t\t\t// Check if this LLM response contains tool calls\n\t\t\t\t\tif (output?.tool_calls && output.tool_calls.length > 0) {\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\tagentResult.intermediateSteps!.push({\n\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\t\t\t\t\ttype: toolCall.type,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_tool_end':\n\t\t\t\t// Capture tool execution results and match with action\n\t\t\t\tif (returnIntermediateSteps && event.data && agentResult.intermediateSteps!.length > 0) {\n\t\t\t\t\tconst toolData = event.data as any;\n\t\t\t\t\t// Find the matching intermediate step for this tool call\n\t\t\t\t\tconst matchingStep = agentResult.intermediateSteps!.find(\n\t\t\t\t\t\t(step) => !step.observation && step.action.tool === event.name,\n\t\t\t\t\t);\n\t\t\t\t\tif (matchingStep) {\n\t\t\t\t\t\tmatchingStep.observation = toolData.output;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\treturn agentResult;\n}\n\nfunction checkIsResponsesApi(model: BaseChatModel | null | undefined): boolean {\n\ttry {\n\t\tconst isUsingResponsesApi =\n\t\t\t!!model && model instanceof ChatOpenAI && 'useResponsesApi' in model && model.useResponsesApi;\n\t\treturn isUsingResponsesApi;\n\t} catch (error) {\n\t\treturn false;\n\t}\n}\n\n/* -----------------------------------------------------------\n Main Executor Function\n----------------------------------------------------------- */\n/**\n * The main executor method for the Tools Agent.\n *\n * This function retrieves necessary components (model, memory, tools), prepares the prompt,\n * creates the agent, and processes each input item. The error handling for each item is also\n * managed here based on the node's continueOnFail setting.\n *\n * @param this Execute context. SupplyDataContext is passed when agent is as a tool\n *\n * @returns The array of execution data for all processed items\n */\nexport async function toolsAgentExecute(\n\tthis: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<INodeExecutionData[][]> {\n\tconst version = this.getNode().typeVersion;\n\tthis.logger.debug('Executing Tools Agent V2');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\t// FIXME: remove when this is fixed: https://github.com/langchain-ai/langchainjs/pull/9082\n\t// Responses API + tools is broken when using langchain default call handling. In V3 calls are handled differently, so it works.\n\tif (checkIsResponsesApi(model)) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t`This model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`,\n\t\t);\n\t}\n\n\tif (checkIsResponsesApi(fallbackModel)) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t`This fallback model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`,\n\t\t);\n\t}\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\t// Check if streaming is enabled\n\tconst enableStreaming = this.getNodeParameter('options.enableStreaming', 0, true) as boolean;\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The \"text\" parameter is empty.');\n\t\t\t}\n\t\t\tconst outputParser = await getOptionalOutputParser(this, itemIndex);\n\t\t\tconst tools = await getTools(this, outputParser);\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\t\t\t// Create executors for primary and fallback models\n\t\t\tconst executor = createAgentExecutor(\n\t\t\t\tmodel,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\toptions,\n\t\t\t\toutputParser,\n\t\t\t\tmemory,\n\t\t\t\tfallbackModel,\n\t\t\t);\n\t\t\t// Invoke with fallback logic\n\t\t\tconst invokeParams = {\n\t\t\t\tinput,\n\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\tformatting_instructions:\n\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t};\n\t\t\tconst executeOptions = { signal: this.getExecutionCancelSignal() };\n\n\t\t\t// Check if streaming is actually available\n\t\t\tconst isStreamingAvailable = 'isStreaming' in this ? this.isStreaming?.() : undefined;\n\n\t\t\tif (\n\t\t\t\t'isStreaming' in this &&\n\t\t\t\tenableStreaming &&\n\t\t\t\tisStreamingAvailable &&\n\t\t\t\tthis.getNode().typeVersion >= 2.1\n\t\t\t) {\n\t\t\t\t// Get chat history respecting the context window length configured in memory\n\t\t\t\tlet chatHistory;\n\t\t\t\tif (memory) {\n\t\t\t\t\t// Load memory variables to respect context window length\n\t\t\t\t\tconst memoryVariables = await memory.loadMemoryVariables({});\n\t\t\t\t\tchatHistory = memoryVariables['chat_history'];\n\t\t\t\t}\n\t\t\t\tconst eventStream = executor.streamEvents(\n\t\t\t\t\t{\n\t\t\t\t\t\t...invokeParams,\n\t\t\t\t\t\tchat_history: chatHistory ?? undefined,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tversion: 'v2',\n\t\t\t\t\t\t...executeOptions,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn await processEventStream(\n\t\t\t\t\tthis,\n\t\t\t\t\teventStream,\n\t\t\t\t\titemIndex,\n\t\t\t\t\toptions.returnIntermediateSteps,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle regular execution\n\t\t\t\treturn await executor.invoke(invokeParams, executeOptions);\n\t\t\t}\n\t\t});\n\n\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\t\t// This is only used to check if the output parser is connected\n\t\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\t\tconst outputParser = await getOptionalOutputParser(this, 0);\n\t\tbatchResults.forEach((result, index) => {\n\t\t\tconst itemIndex = i + index;\n\t\t\tif (result.status === 'rejected') {\n\t\t\t\tconst error = result.reason as Error;\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst response = result.value;\n\t\t\t// If memory and outputParser are connected, parse the output.\n\t\t\tif (memory && outputParser) {\n\t\t\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(\n\t\t\t\t\tresponse.output as string,\n\t\t\t\t);\n\t\t\t\tresponse.output = parsedOutput?.output ?? parsedOutput;\n\t\t\t}\n\n\t\t\t// Omit internal keys before returning the result.\n\t\t\tconst itemResult = {\n\t\t\t\tjson: omit(\n\t\t\t\t\tresponse,\n\t\t\t\t\t'system_message',\n\t\t\t\t\t'formatting_instructions',\n\t\t\t\t\t'input',\n\t\t\t\t\t'chat_history',\n\t\t\t\t\t'agent_scratchpad',\n\t\t\t\t),\n\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t};\n\n\t\t\treturnData.push(itemResult);\n\t\t});\n\n\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\tawait sleep(delayBetweenBatches);\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,uBAAiC;AACjC,oBAIO;AAGP,kBAAiB;AACjB,0BAAqD;AAErD,yBAAmB;AAEnB,qBAAqC;AACrC,6BAGO;AAEP,oBAQO;AACP,oBAA+B;AAC/B,oBAA2B;AAK3B,SAAS,oBACR,OACA,OACA,QACA,SACA,cACA,QACA,eACC;AACD,QAAM,YAAQ,sCAAuB;AAAA,IACpC,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EACjB,CAAC;AAED,MAAI;AACJ,MAAI,eAAe;AAClB,wBAAgB,sCAAuB;AAAA,MACtC,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IACjB,CAAC;AAAA,EACF;AACA,QAAM,gBAAgB,kCAAiB,KAAK;AAAA,IAC3C,gBAAgB,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI;AAAA,QACvD,mCAAoB,cAAc,MAAM;AAAA,IACxC;AAAA,EACD,CAAC;AAED,gBAAc,eAAe;AAC7B,gBAAc,iBAAiB;AAE/B,SAAO,4BAAc,kBAAkB;AAAA,IACtC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,yBAAyB,QAAQ,4BAA4B;AAAA,IAC7D,eAAe,QAAQ,iBAAiB;AAAA,EACzC,CAAC;AACF;AAEA,eAAe,mBACd,KACA,aACA,WACA,0BAAmC,OACsB;AACzD,QAAM,cAA6D;AAAA,IAClE,QAAQ;AAAA,EACT;AAEA,MAAI,yBAAyB;AAC5B,gBAAY,oBAAoB,CAAC;AAAA,EAClC;AAEA,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,2BAA2B,MAAM,MAAM;AAC1C,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,SAAS,cAAc;AAG7B,cAAI,QAAQ,cAAc,OAAO,WAAW,SAAS,GAAG;AACvD,uBAAW,YAAY,OAAO,YAAY;AACzC,0BAAY,kBAAmB,KAAK;AAAA,gBACnC,QAAQ;AAAA,kBACP,MAAM,SAAS;AAAA,kBACf,WAAW,SAAS;AAAA,kBACpB,KACC,OAAO,WACP,WAAW,SAAS,IAAI,gBAAgB,KAAK,UAAU,SAAS,IAAI,CAAC;AAAA,kBACtE,YAAY,CAAC,MAAM;AAAA;AAAA,kBACnB,YAAY,SAAS;AAAA,kBACrB,MAAM,SAAS;AAAA,gBAChB;AAAA,cACD,CAAC;AAAA,YACF;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD,KAAK;AAEJ,YAAI,2BAA2B,MAAM,QAAQ,YAAY,kBAAmB,SAAS,GAAG;AACvF,gBAAM,WAAW,MAAM;AAEvB,gBAAM,eAAe,YAAY,kBAAmB;AAAA,YACnD,CAAC,SAAS,CAAC,KAAK,eAAe,KAAK,OAAO,SAAS,MAAM;AAAA,UAC3D;AACA,cAAI,cAAc;AACjB,yBAAa,cAAc,SAAS;AAAA,UACrC;AAAA,QACD;AACA;AAAA,MACD;AACC;AAAA,IACF;AAAA,EACD;AACA,MAAI,UAAU,OAAO,SAAS;AAE9B,SAAO;AACR;AAEA,SAAS,oBAAoB,OAAkD;AAC9E,MAAI;AACH,UAAM,sBACL,CAAC,CAAC,SAAS,iBAAiB,4BAAc,qBAAqB,SAAS,MAAM;AAC/E,WAAO;AAAA,EACR,SAAS,OAAO;AACf,WAAO;AAAA,EACR;AACD;AAgBA,eAAsB,oBAEa;AAClC,QAAM,UAAU,KAAK,QAAQ,EAAE;AAC/B,OAAK,OAAO,MAAM,0BAA0B;AAE5C,QAAM,aAAmC,CAAC;AAC1C,QAAM,QAAQ,KAAK,aAAa;AAChC,QAAM,YAAY,KAAK,iBAAiB,8BAA8B,GAAG,CAAC;AAC1E,QAAM,sBAAsB,KAAK;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,gBAAgB,KAAK,iBAAiB,iBAAiB,GAAG,KAAK;AACrE,QAAM,SAAS,UAAM,iCAAkB,IAAI;AAC3C,QAAM,QAAQ,UAAM,4BAAa,MAAM,CAAC;AACxC,yBAAAA,SAAO,OAAO,gDAAgD;AAC9D,QAAM,gBAAgB,gBAAgB,UAAM,4BAAa,MAAM,CAAC,IAAI;AAIpE,MAAI,oBAAoB,KAAK,GAAG;AAC/B,UAAM,IAAI;AAAA,MACT,KAAK,QAAQ;AAAA,MACb,kCAAkC,OAAO;AAAA,IAC1C;AAAA,EACD;AAEA,MAAI,oBAAoB,aAAa,GAAG;AACvC,UAAM,IAAI;AAAA,MACT,KAAK,QAAQ;AAAA,MACb,2CAA2C,OAAO;AAAA,IACnD;AAAA,EACD;AAEA,MAAI,iBAAiB,CAAC,eAAe;AACpC,UAAM,IAAI;AAAA,MACT,KAAK,QAAQ;AAAA,MACb;AAAA,IACD;AAAA,EACD;AAGA,QAAM,kBAAkB,KAAK,iBAAiB,2BAA2B,GAAG,IAAI;AAEhF,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AACjD,UAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,SAAS;AAC1C,UAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,mBAAmB;AAChE,YAAM,YAAY,IAAI;AAEtB,YAAM,YAAQ,qCAAqB;AAAA,QAClC,KAAK;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,eAAe;AAAA,MAChB,CAAC;AACD,UAAI,UAAU,QAAW;AACxB,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,gCAAgC;AAAA,MAC9E;AACA,YAAMC,gBAAe,UAAM,gDAAwB,MAAM,SAAS;AAClE,YAAM,QAAQ,UAAM,wBAAS,MAAMA,aAAY;AAC/C,YAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAQ9D,YAAM,WAAW,UAAM,+BAAgB,MAAM,WAAW;AAAA,QACvD,eAAe,QAAQ;AAAA,QACvB,yBAAyB,QAAQ,2BAA2B;AAAA,QAC5D,cAAAA;AAAA,MACD,CAAC;AACD,YAAM,aAA6B,6BAAc,QAAQ;AAGzD,YAAM,WAAW;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAEA,YAAM,eAAe;AAAA,QACpB;AAAA,QACA,gBAAgB,QAAQ,iBAAiB;AAAA,QACzC,yBACC;AAAA,MACF;AACA,YAAM,iBAAiB,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAGjE,YAAM,uBAAuB,iBAAiB,OAAO,KAAK,cAAc,IAAI;AAE5E,UACC,iBAAiB,QACjB,mBACA,wBACA,KAAK,QAAQ,EAAE,eAAe,KAC7B;AAED,YAAI;AACJ,YAAI,QAAQ;AAEX,gBAAM,kBAAkB,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAC3D,wBAAc,gBAAgB,cAAc;AAAA,QAC7C;AACA,cAAM,cAAc,SAAS;AAAA,UAC5B;AAAA,YACC,GAAG;AAAA,YACH,cAAc,eAAe;AAAA,UAC9B;AAAA,UACA;AAAA,YACC,SAAS;AAAA,YACT,GAAG;AAAA,UACJ;AAAA,QACD;AAEA,eAAO,MAAM;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,QACT;AAAA,MACD,OAAO;AAEN,eAAO,MAAM,SAAS,OAAO,cAAc,cAAc;AAAA,MAC1D;AAAA,IACD,CAAC;AAED,UAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAG3D,UAAM,eAAe,UAAM,gDAAwB,MAAM,CAAC;AAC1D,iBAAa,QAAQ,CAAC,QAAQ,UAAU;AACvC,YAAM,YAAY,IAAI;AACtB,UAAI,OAAO,WAAW,YAAY;AACjC,cAAM,QAAQ,OAAO;AACrB,YAAI,KAAK,eAAe,GAAG;AAC1B,qBAAW,KAAK;AAAA,YACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,YAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,UAC/B,CAAC;AACD;AAAA,QACD,OAAO;AACN,gBAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,KAAK;AAAA,QACnD;AAAA,MACD;AACA,YAAM,WAAW,OAAO;AAExB,UAAI,UAAU,cAAc;AAC3B,cAAM,mBAAe;AAAA,UACpB,SAAS;AAAA,QACV;AACA,iBAAS,SAAS,cAAc,UAAU;AAAA,MAC3C;AAGA,YAAM,aAAa;AAAA,QAClB,UAAM,YAAAC;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD;AAAA,QACA,YAAY,EAAE,MAAM,UAAU;AAAA,MAC/B;AAEA,iBAAW,KAAK,UAAU;AAAA,IAC3B,CAAC;AAED,QAAI,IAAI,YAAY,MAAM,UAAU,sBAAsB,GAAG;AAC5D,gBAAM,2BAAM,mBAAmB;AAAA,IAChC;AAAA,EACD;AAEA,SAAO,CAAC,UAAU;AACnB;","names":["assert","outputParser","omit"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/buildExecutionContext.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions, INodeExecutionData } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getChatModel, getOptionalMemory } from '../../common';\n\n/**\n * Execution context that contains shared configuration needed across all items\n */\nexport type ToolsAgentExecutionContext = {\n\titems: INodeExecutionData[];\n\tbatchSize: number;\n\tdelayBetweenBatches: number;\n\tneedsFallback: boolean;\n\tmodel: BaseChatModel;\n\tfallbackModel: BaseChatModel | null;\n\tmemory: BaseChatMemory | undefined;\n};\n\n/**\n * Builds the execution context by collecting shared configuration\n * such as models, memory, batching settings, and streaming flags.\n *\n * @param ctx - The execution context (IExecuteFunctions or ISupplyDataFunctions)\n * @returns ExecutionContext containing all shared configuration\n */\nexport async function buildToolsAgentExecutionContext(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<ToolsAgentExecutionContext> {\n\tconst items = ctx.getInputData();\n\tconst batchSize = ctx.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = ctx.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = ctx.getNodeParameter('needsFallback', 0, false) as boolean;\n\n\tconst memory = await getOptionalMemory(ctx);\n\tconst model = await getChatModel(ctx, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\n\tlet fallbackModel: BaseChatModel | null = null;\n\tif (needsFallback) {\n\t\tconst maybeFallbackModel = await getChatModel(ctx, 1);\n\t\tif (!maybeFallbackModel) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tctx.getNode(),\n\t\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t\t);\n\t\t}\n\t\tfallbackModel = maybeFallbackModel;\n\t}\n\n\treturn {\n\t\titems,\n\t\tbatchSize,\n\t\tdelayBetweenBatches,\n\t\tneedsFallback,\n\t\tmodel,\n\t\tfallbackModel,\n\t\tmemory,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAmC;AAEnC,yBAAmB;AAEnB,oBAAgD;AAsBhD,eAAsB,gCACrB,KACsC;AACtC,QAAM,QAAQ,IAAI,aAAa;AAC/B,QAAM,YAAY,IAAI,iBAAiB,8BAA8B,GAAG,CAAC;AACzE,QAAM,sBAAsB,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,gBAAgB,IAAI,iBAAiB,iBAAiB,GAAG,KAAK;AAEpE,QAAM,SAAS,UAAM,iCAAkB,GAAG;AAC1C,QAAM,QAAQ,UAAM,4BAAa,KAAK,CAAC;AACvC,yBAAAA,SAAO,OAAO,gDAAgD;AAE9D,MAAI,gBAAsC;AAC1C,MAAI,eAAe;AAClB,UAAM,qBAAqB,UAAM,4BAAa,KAAK,CAAC;AACpD,QAAI,CAAC,oBAAoB;AACxB,YAAM,IAAI;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AACA,oBAAgB;AAAA,EACjB;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;","names":["assert"]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/buildExecutionContext.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions, INodeExecutionData } from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getChatModel, getOptionalMemory } from '../../common';\n\n/**\n * Execution context that contains shared configuration needed across all items\n */\nexport type ToolsAgentExecutionContext = {\n\titems: INodeExecutionData[];\n\tbatchSize: number;\n\tdelayBetweenBatches: number;\n\tneedsFallback: boolean;\n\tmodel: BaseChatModel;\n\tfallbackModel: BaseChatModel | null;\n\tmemory: BaseChatMemory | undefined;\n};\n\n/**\n * Builds the execution context by collecting shared configuration\n * such as models, memory, batching settings, and streaming flags.\n *\n * @param ctx - The execution context (IExecuteFunctions or ISupplyDataFunctions)\n * @returns ExecutionContext containing all shared configuration\n */\nexport async function buildToolsAgentExecutionContext(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<ToolsAgentExecutionContext> {\n\tconst items = ctx.getInputData();\n\tconst batchSize = ctx.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = ctx.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = ctx.getNodeParameter('needsFallback', 0, false) as boolean;\n\n\tconst memory = await getOptionalMemory(ctx);\n\tconst model = await getChatModel(ctx, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\n\tlet fallbackModel: BaseChatModel | null = null;\n\tif (needsFallback) {\n\t\tconst maybeFallbackModel = await getChatModel(ctx, 1);\n\t\tif (!maybeFallbackModel) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tctx.getNode(),\n\t\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t\t);\n\t\t}\n\t\tfallbackModel = maybeFallbackModel;\n\t}\n\n\treturn {\n\t\titems,\n\t\tbatchSize,\n\t\tdelayBetweenBatches,\n\t\tneedsFallback,\n\t\tmodel,\n\t\tfallbackModel,\n\t\tmemory,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAmC;AAEnC,yBAAmB;AAEnB,oBAAgD;AAsBhD,eAAsB,gCACrB,KACsC;AACtC,QAAM,QAAQ,IAAI,aAAa;AAC/B,QAAM,YAAY,IAAI,iBAAiB,8BAA8B,GAAG,CAAC;AACzE,QAAM,sBAAsB,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,gBAAgB,IAAI,iBAAiB,iBAAiB,GAAG,KAAK;AAEpE,QAAM,SAAS,UAAM,iCAAkB,GAAG;AAC1C,QAAM,QAAQ,UAAM,4BAAa,KAAK,CAAC;AACvC,yBAAAA,SAAO,OAAO,gDAAgD;AAE9D,MAAI,gBAAsC;AAC1C,MAAI,eAAe;AAClB,UAAM,qBAAqB,UAAM,4BAAa,KAAK,CAAC;AACpD,QAAI,CAAC,oBAAoB;AACxB,YAAM,IAAI;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AACA,oBAAgB;AAAA,EACjB;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;","names":["assert"]}
@@ -22,7 +22,7 @@ __export(createAgentSequence_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(createAgentSequence_exports);
24
24
  var import_runnables = require("@langchain/core/runnables");
25
- var import_agents = require("langchain/agents");
25
+ var import_agents = require("@langchain/classic/agents");
26
26
  var import_common = require("../../common");
27
27
  function createAgentSequence(model, tools, prompt, _options, outputParser, memory, fallbackModel) {
28
28
  const agent = (0, import_agents.createToolCallingAgent)({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport { type AgentRunnableSequence, createToolCallingAgent } from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\n\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport { fixEmptyContentMessage, getAgentStepsParser } from '../../common';\n\n/**\n * Creates an agent sequence with the given configuration.\n * The sequence includes the agent, output parser, and fallback logic.\n *\n * @param model - The primary chat model\n * @param tools - Array of tools available to the agent\n * @param prompt - The prompt template\n * @param _options - Additional options (maxIterations, returnIntermediateSteps)\n * @param outputParser - Optional output parser for structured responses\n * @param memory - Optional memory for conversation context\n * @param fallbackModel - Optional fallback model if primary fails\n * @returns AgentRunnableSequence ready for execution\n */\nexport function createAgentSequence(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\t_options: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools: getAllTools(model, tools),\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools: getAllTools(fallbackModel, tools),\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]) as AgentRunnableSequence;\n\n\trunnableAgent.singleAction = true;\n\trunnableAgent.streamRunnable = false;\n\n\treturn runnableAgent;\n}\n\n/**\n * Uses provided tools and tried to get tools from model metadata\n * Some chat model nodes can define built-in tools in their metadata\n */\nfunction getAllTools(model: BaseChatModel, tools: Array<DynamicStructuredTool | Tool>) {\n\tconst modelTools = (model.metadata?.tools as Tool[]) ?? [];\n\tconst allTools = [...tools, ...modelTools];\n\treturn allTools;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAiC;AACjC,oBAAmE;AAMnE,oBAA4D;AAerD,SAAS,oBACf,OACA,OACA,QACA,UACA,cACA,QACA,eACC;AACD,QAAM,YAAQ,sCAAuB;AAAA,IACpC,KAAK;AAAA,IACL,OAAO,YAAY,OAAO,KAAK;AAAA,IAC/B;AAAA,IACA,gBAAgB;AAAA,EACjB,CAAC;AAED,MAAI;AACJ,MAAI,eAAe;AAClB,wBAAgB,sCAAuB;AAAA,MACtC,KAAK;AAAA,MACL,OAAO,YAAY,eAAe,KAAK;AAAA,MACvC;AAAA,MACA,gBAAgB;AAAA,IACjB,CAAC;AAAA,EACF;AACA,QAAM,gBAAgB,kCAAiB,KAAK;AAAA,IAC3C,gBAAgB,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI;AAAA,QACvD,mCAAoB,cAAc,MAAM;AAAA,IACxC;AAAA,EACD,CAAC;AAED,gBAAc,eAAe;AAC7B,gBAAc,iBAAiB;AAE/B,SAAO;AACR;AAMA,SAAS,YAAY,OAAsB,OAA4C;AACtF,QAAM,aAAc,MAAM,UAAU,SAAoB,CAAC;AACzD,QAAM,WAAW,CAAC,GAAG,OAAO,GAAG,UAAU;AACzC,SAAO;AACR;","names":[]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport { RunnableSequence } from '@langchain/core/runnables';\nimport { type AgentRunnableSequence, createToolCallingAgent } from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport type { DynamicStructuredTool, Tool } from '@langchain/classic/tools';\n\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport { fixEmptyContentMessage, getAgentStepsParser } from '../../common';\n\n/**\n * Creates an agent sequence with the given configuration.\n * The sequence includes the agent, output parser, and fallback logic.\n *\n * @param model - The primary chat model\n * @param tools - Array of tools available to the agent\n * @param prompt - The prompt template\n * @param _options - Additional options (maxIterations, returnIntermediateSteps)\n * @param outputParser - Optional output parser for structured responses\n * @param memory - Optional memory for conversation context\n * @param fallbackModel - Optional fallback model if primary fails\n * @returns AgentRunnableSequence ready for execution\n */\nexport function createAgentSequence(\n\tmodel: BaseChatModel,\n\ttools: Array<DynamicStructuredTool | Tool>,\n\tprompt: ChatPromptTemplate,\n\t_options: { maxIterations?: number; returnIntermediateSteps?: boolean },\n\toutputParser?: N8nOutputParser,\n\tmemory?: BaseChatMemory,\n\tfallbackModel?: BaseChatModel | null,\n) {\n\tconst agent = createToolCallingAgent({\n\t\tllm: model,\n\t\ttools: getAllTools(model, tools),\n\t\tprompt,\n\t\tstreamRunnable: false,\n\t});\n\n\tlet fallbackAgent: AgentRunnableSequence | undefined;\n\tif (fallbackModel) {\n\t\tfallbackAgent = createToolCallingAgent({\n\t\t\tllm: fallbackModel,\n\t\t\ttools: getAllTools(fallbackModel, tools),\n\t\t\tprompt,\n\t\t\tstreamRunnable: false,\n\t\t});\n\t}\n\tconst runnableAgent = RunnableSequence.from([\n\t\tfallbackAgent ? agent.withFallbacks([fallbackAgent]) : agent,\n\t\tgetAgentStepsParser(outputParser, memory),\n\t\tfixEmptyContentMessage,\n\t]) as AgentRunnableSequence;\n\n\trunnableAgent.singleAction = true;\n\trunnableAgent.streamRunnable = false;\n\n\treturn runnableAgent;\n}\n\n/**\n * Uses provided tools and tried to get tools from model metadata\n * Some chat model nodes can define built-in tools in their metadata\n */\nfunction getAllTools(model: BaseChatModel, tools: Array<DynamicStructuredTool | Tool>) {\n\tconst modelTools = (model.metadata?.tools as Tool[]) ?? [];\n\tconst allTools = [...tools, ...modelTools];\n\treturn allTools;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAiC;AACjC,oBAAmE;AAMnE,oBAA4D;AAerD,SAAS,oBACf,OACA,OACA,QACA,UACA,cACA,QACA,eACC;AACD,QAAM,YAAQ,sCAAuB;AAAA,IACpC,KAAK;AAAA,IACL,OAAO,YAAY,OAAO,KAAK;AAAA,IAC/B;AAAA,IACA,gBAAgB;AAAA,EACjB,CAAC;AAED,MAAI;AACJ,MAAI,eAAe;AAClB,wBAAgB,sCAAuB;AAAA,MACtC,KAAK;AAAA,MACL,OAAO,YAAY,eAAe,KAAK;AAAA,MACvC;AAAA,MACA,gBAAgB;AAAA,IACjB,CAAC;AAAA,EACF;AACA,QAAM,gBAAgB,kCAAiB,KAAK;AAAA,IAC3C,gBAAgB,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI;AAAA,QACvD,mCAAoB,cAAc,MAAM;AAAA,IACxC;AAAA,EACD,CAAC;AAED,gBAAc,eAAe;AAC7B,gBAAc,iBAAiB;AAE/B,SAAO;AACR;AAMA,SAAS,YAAY,OAAsB,OAA4C;AACtF,QAAM,aAAc,MAAM,UAAU,SAAoB,CAAC;AACzD,QAAM,WAAW,CAAC,GAAG,OAAO,GAAG,UAAU;AACzC,SAAO;AACR;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tINodeExecutionData,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport type { RequestResponseMetadata, AgentResult } from '../types';\nimport { createAgentSequence } from './createAgentSequence';\nimport { finalizeResult } from './finalizeResult';\nimport { prepareItemContext } from './prepareItemContext';\nimport { runAgent } from './runAgent';\n\ntype BatchResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Executes a batch of items, handling both successful execution and errors.\n * Applies continue-on-fail logic when errors occur.\n *\n * @param ctx - The execution context\n * @param batch - Array of items to process in this batch\n * @param startIndex - Starting index of the batch in the original items array (used to calculate itemIndex)\n * @param model - Primary chat model\n * @param fallbackModel - Optional fallback model\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns Object containing execution data and optional requests\n */\nexport async function executeBatch(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\tbatch: INodeExecutionData[],\n\tstartIndex: number,\n\tmodel: BaseChatModel,\n\tfallbackModel: BaseChatModel | null,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<{\n\treturnData: INodeExecutionData[];\n\trequest: EngineRequest<RequestResponseMetadata> | undefined;\n}> {\n\tconst returnData: INodeExecutionData[] = [];\n\tlet request: EngineRequest<RequestResponseMetadata> | undefined = undefined;\n\n\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\tconst itemIndex = startIndex + batchItemIndex;\n\n\t\tconst itemContext = await prepareItemContext(ctx, itemIndex, response);\n\n\t\tconst { tools, prompt, options, outputParser } = itemContext;\n\n\t\t// Create executors for primary and fallback models\n\t\tconst executor: AgentRunnableSequence = createAgentSequence(\n\t\t\tmodel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\toptions,\n\t\t\toutputParser,\n\t\t\tmemory,\n\t\t\tfallbackModel,\n\t\t);\n\n\t\t// Run the agent\n\t\treturn await runAgent(ctx, executor, itemContext, model, memory, response);\n\t});\n\n\tconst batchResults = await Promise.allSettled(batchPromises);\n\t// This is only used to check if the output parser is connected\n\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\tconst outputParser = await getOptionalOutputParser(ctx, 0);\n\n\tbatchResults.forEach((result, index) => {\n\t\tconst itemIndex = startIndex + index;\n\t\tif (result.status === 'rejected') {\n\t\t\tconst error = result.reason as Error;\n\t\t\tif (ctx.continueOnFail()) {\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t} as INodeExecutionData);\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tthrow new NodeOperationError(ctx.getNode(), error);\n\t\t\t}\n\t\t}\n\t\tconst batchResult = result.value as BatchResult;\n\n\t\tif (!batchResult) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('actions' in batchResult) {\n\t\t\tif (!request) {\n\t\t\t\trequest = {\n\t\t\t\t\tactions: batchResult.actions,\n\t\t\t\t\tmetadata: batchResult.metadata,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\trequest.actions.push.apply(request.actions, batchResult.actions);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Finalize the result\n\t\tconst itemResult = finalizeResult(batchResult, itemIndex, memory, outputParser);\n\t\treturnData.push(itemResult);\n\t});\n\n\treturn { returnData, request };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAAmC;AASnC,6BAAwC;AAGxC,iCAAoC;AACpC,4BAA+B;AAC/B,gCAAmC;AACnC,sBAAyB;AAgBzB,eAAsB,aACrB,KACA,OACA,YACA,OACA,eACA,QACA,UAIE;AACF,QAAM,aAAmC,CAAC;AAC1C,MAAI,UAA8D;AAElE,QAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,mBAAmB;AAChE,UAAM,YAAY,aAAa;AAE/B,UAAM,cAAc,UAAM,8CAAmB,KAAK,WAAW,QAAQ;AAErE,UAAM,EAAE,OAAO,QAAQ,SAAS,cAAAA,cAAa,IAAI;AAGjD,UAAM,eAAkC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACAA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAGA,WAAO,UAAM,0BAAS,KAAK,UAAU,aAAa,OAAO,QAAQ,QAAQ;AAAA,EAC1E,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAG3D,QAAM,eAAe,UAAM,gDAAwB,KAAK,CAAC;AAEzD,eAAa,QAAQ,CAAC,QAAQ,UAAU;AACvC,UAAM,YAAY,aAAa;AAC/B,QAAI,OAAO,WAAW,YAAY;AACjC,YAAM,QAAQ,OAAO;AACrB,UAAI,IAAI,eAAe,GAAG;AACzB,mBAAW,KAAK;AAAA,UACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,UAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,QAC/B,CAAuB;AACvB;AAAA,MACD,OAAO;AACN,cAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,KAAK;AAAA,MAClD;AAAA,IACD;AACA,UAAM,cAAc,OAAO;AAE3B,QAAI,CAAC,aAAa;AACjB;AAAA,IACD;AAEA,QAAI,aAAa,aAAa;AAC7B,UAAI,CAAC,SAAS;AACb,kBAAU;AAAA,UACT,SAAS,YAAY;AAAA,UACrB,UAAU,YAAY;AAAA,QACvB;AAAA,MACD,OAAO;AACN,gBAAQ,QAAQ,KAAK,MAAM,QAAQ,SAAS,YAAY,OAAO;AAAA,MAChE;AACA;AAAA,IACD;AAGA,UAAM,iBAAa,sCAAe,aAAa,WAAW,QAAQ,YAAY;AAC9E,eAAW,KAAK,UAAU;AAAA,EAC3B,CAAC;AAED,SAAO,EAAE,YAAY,QAAQ;AAC9B;","names":["outputParser"]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tINodeExecutionData,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport type { RequestResponseMetadata, AgentResult } from '../types';\nimport { createAgentSequence } from './createAgentSequence';\nimport { finalizeResult } from './finalizeResult';\nimport { prepareItemContext } from './prepareItemContext';\nimport { runAgent } from './runAgent';\n\ntype BatchResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Executes a batch of items, handling both successful execution and errors.\n * Applies continue-on-fail logic when errors occur.\n *\n * @param ctx - The execution context\n * @param batch - Array of items to process in this batch\n * @param startIndex - Starting index of the batch in the original items array (used to calculate itemIndex)\n * @param model - Primary chat model\n * @param fallbackModel - Optional fallback model\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns Object containing execution data and optional requests\n */\nexport async function executeBatch(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\tbatch: INodeExecutionData[],\n\tstartIndex: number,\n\tmodel: BaseChatModel,\n\tfallbackModel: BaseChatModel | null,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<{\n\treturnData: INodeExecutionData[];\n\trequest: EngineRequest<RequestResponseMetadata> | undefined;\n}> {\n\tconst returnData: INodeExecutionData[] = [];\n\tlet request: EngineRequest<RequestResponseMetadata> | undefined = undefined;\n\n\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\tconst itemIndex = startIndex + batchItemIndex;\n\n\t\tconst itemContext = await prepareItemContext(ctx, itemIndex, response);\n\n\t\tconst { tools, prompt, options, outputParser } = itemContext;\n\n\t\t// Create executors for primary and fallback models\n\t\tconst executor: AgentRunnableSequence = createAgentSequence(\n\t\t\tmodel,\n\t\t\ttools,\n\t\t\tprompt,\n\t\t\toptions,\n\t\t\toutputParser,\n\t\t\tmemory,\n\t\t\tfallbackModel,\n\t\t);\n\n\t\t// Run the agent\n\t\treturn await runAgent(ctx, executor, itemContext, model, memory, response);\n\t});\n\n\tconst batchResults = await Promise.allSettled(batchPromises);\n\t// This is only used to check if the output parser is connected\n\t// so we can parse the output if needed. Actual output parsing is done in the loop above\n\tconst outputParser = await getOptionalOutputParser(ctx, 0);\n\n\tbatchResults.forEach((result, index) => {\n\t\tconst itemIndex = startIndex + index;\n\t\tif (result.status === 'rejected') {\n\t\t\tconst error = result.reason as Error;\n\t\t\tif (ctx.continueOnFail()) {\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t} as INodeExecutionData);\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tthrow new NodeOperationError(ctx.getNode(), error);\n\t\t\t}\n\t\t}\n\t\tconst batchResult = result.value as BatchResult;\n\n\t\tif (!batchResult) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('actions' in batchResult) {\n\t\t\tif (!request) {\n\t\t\t\trequest = {\n\t\t\t\t\tactions: batchResult.actions,\n\t\t\t\t\tmetadata: batchResult.metadata,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\trequest.actions.push.apply(request.actions, batchResult.actions);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Finalize the result\n\t\tconst itemResult = finalizeResult(batchResult, itemIndex, memory, outputParser);\n\t\treturnData.push(itemResult);\n\t});\n\n\treturn { returnData, request };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAAmC;AASnC,6BAAwC;AAGxC,iCAAoC;AACpC,4BAA+B;AAC/B,gCAAmC;AACnC,sBAAyB;AAgBzB,eAAsB,aACrB,KACA,OACA,YACA,OACA,eACA,QACA,UAIE;AACF,QAAM,aAAmC,CAAC;AAC1C,MAAI,UAA8D;AAElE,QAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,mBAAmB;AAChE,UAAM,YAAY,aAAa;AAE/B,UAAM,cAAc,UAAM,8CAAmB,KAAK,WAAW,QAAQ;AAErE,UAAM,EAAE,OAAO,QAAQ,SAAS,cAAAA,cAAa,IAAI;AAGjD,UAAM,eAAkC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACAA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAGA,WAAO,UAAM,0BAAS,KAAK,UAAU,aAAa,OAAO,QAAQ,QAAQ;AAAA,EAC1E,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAG3D,QAAM,eAAe,UAAM,gDAAwB,KAAK,CAAC;AAEzD,eAAa,QAAQ,CAAC,QAAQ,UAAU;AACvC,UAAM,YAAY,aAAa;AAC/B,QAAI,OAAO,WAAW,YAAY;AACjC,YAAM,QAAQ,OAAO;AACrB,UAAI,IAAI,eAAe,GAAG;AACzB,mBAAW,KAAK;AAAA,UACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,UAC7B,YAAY,EAAE,MAAM,UAAU;AAAA,QAC/B,CAAuB;AACvB;AAAA,MACD,OAAO;AACN,cAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,KAAK;AAAA,MAClD;AAAA,IACD;AACA,UAAM,cAAc,OAAO;AAE3B,QAAI,CAAC,aAAa;AACjB;AAAA,IACD;AAEA,QAAI,aAAa,aAAa;AAC7B,UAAI,CAAC,SAAS;AACb,kBAAU;AAAA,UACT,SAAS,YAAY;AAAA,UACrB,UAAU,YAAY;AAAA,QACvB;AAAA,MACD,OAAO;AACN,gBAAQ,QAAQ,KAAK,MAAM,QAAQ,SAAS,YAAY,OAAO;AAAA,MAChE;AACA;AAAA,IACD;AAGA,UAAM,iBAAa,sCAAe,aAAa,WAAW,QAAQ,YAAY;AAC9E,eAAW,KAAK,UAAU;AAAA,EAC3B,CAAC;AAED,SAAO,EAAE,YAAY,QAAQ;AAC9B;","names":["outputParser"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/finalizeResult.ts"],"sourcesContent":["import type { BaseChatMemory } from 'langchain/memory';\nimport omit from 'lodash/omit';\nimport { jsonParse } from 'n8n-workflow';\nimport type { INodeExecutionData } from 'n8n-workflow';\n\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport type { AgentResult } from '../types';\n\n/**\n * Finalizes the result by parsing output and preparing execution data.\n * Handles output parser integration and memory-based parsing.\n *\n * @param result - The agent result to finalize\n * @param itemIndex - The current item index\n * @param memory - Optional memory for parsing context\n * @param outputParser - Optional output parser for structured responses\n * @returns INodeExecutionData ready for output\n */\nexport function finalizeResult(\n\tresult: AgentResult,\n\titemIndex: number,\n\tmemory: BaseChatMemory | undefined,\n\toutputParser: N8nOutputParser | undefined,\n): INodeExecutionData {\n\t// If memory and outputParser are connected, parse the output.\n\tif (memory && outputParser) {\n\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(result.output);\n\t\t// Type assertion needed because parsedOutput can be various types\n\t\tresult.output = (parsedOutput?.output ?? parsedOutput) as unknown as string;\n\t}\n\n\t// Omit internal keys before returning the result.\n\tconst itemResult: INodeExecutionData = {\n\t\tjson: omit(\n\t\t\tresult,\n\t\t\t'system_message',\n\t\t\t'formatting_instructions',\n\t\t\t'input',\n\t\t\t'chat_history',\n\t\t\t'agent_scratchpad',\n\t\t),\n\t\tpairedItem: { item: itemIndex },\n\t};\n\n\treturn itemResult;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiB;AACjB,0BAA0B;AAiBnB,SAAS,eACf,QACA,WACA,QACA,cACqB;AAErB,MAAI,UAAU,cAAc;AAC3B,UAAM,mBAAe,+BAA+C,OAAO,MAAM;AAEjF,WAAO,SAAU,cAAc,UAAU;AAAA,EAC1C;AAGA,QAAM,aAAiC;AAAA,IACtC,UAAM,YAAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA,YAAY,EAAE,MAAM,UAAU;AAAA,EAC/B;AAEA,SAAO;AACR;","names":["omit"]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/finalizeResult.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/classic/memory';\nimport omit from 'lodash/omit';\nimport { jsonParse } from 'n8n-workflow';\nimport type { INodeExecutionData } from 'n8n-workflow';\n\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport type { AgentResult } from '../types';\n\n/**\n * Finalizes the result by parsing output and preparing execution data.\n * Handles output parser integration and memory-based parsing.\n *\n * @param result - The agent result to finalize\n * @param itemIndex - The current item index\n * @param memory - Optional memory for parsing context\n * @param outputParser - Optional output parser for structured responses\n * @returns INodeExecutionData ready for output\n */\nexport function finalizeResult(\n\tresult: AgentResult,\n\titemIndex: number,\n\tmemory: BaseChatMemory | undefined,\n\toutputParser: N8nOutputParser | undefined,\n): INodeExecutionData {\n\t// If memory and outputParser are connected, parse the output.\n\tif (memory && outputParser) {\n\t\tconst parsedOutput = jsonParse<{ output: Record<string, unknown> }>(result.output);\n\t\t// Type assertion needed because parsedOutput can be various types\n\t\tresult.output = (parsedOutput?.output ?? parsedOutput) as unknown as string;\n\t}\n\n\t// Omit internal keys before returning the result.\n\tconst itemResult: INodeExecutionData = {\n\t\tjson: omit(\n\t\t\tresult,\n\t\t\t'system_message',\n\t\t\t'formatting_instructions',\n\t\t\t'input',\n\t\t\t'chat_history',\n\t\t\t'agent_scratchpad',\n\t\t),\n\t\tpairedItem: { item: itemIndex },\n\t};\n\n\treturn itemResult;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiB;AACjB,0BAA0B;AAiBnB,SAAS,eACf,QACA,WACA,QACA,cACqB;AAErB,MAAI,UAAU,cAAc;AAC3B,UAAM,mBAAe,+BAA+C,OAAO,MAAM;AAEjF,WAAO,SAAU,cAAc,UAAU;AAAA,EAC1C;AAGA,QAAM,aAAiC;AAAA,IACtC,UAAM,YAAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA,YAAY,EAAE,MAAM,UAAU;AAAA,EAC/B;AAEA,SAAO;AACR;","names":["omit"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/prepareItemContext.ts"],"sourcesContent":["import type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions, EngineResponse } from 'n8n-workflow';\n\nimport { buildSteps, type ToolCallData } from '@utils/agent-execution';\nimport { getPromptInputByType } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport { getTools, prepareMessages, preparePrompt } from '../../common';\nimport type { AgentOptions, RequestResponseMetadata } from '../types';\n\n/**\n * Context specific to a single item's processing\n */\nexport type ItemContext = {\n\titemIndex: number;\n\tinput: string;\n\tsteps: ToolCallData[];\n\ttools: Array<DynamicStructuredTool | Tool>;\n\tprompt: ChatPromptTemplate;\n\toptions: AgentOptions;\n\toutputParser: N8nOutputParser | undefined;\n};\n\n/**\n * Prepares the context for processing a single item.\n * This includes loading steps, input, tools, prompt, and options.\n *\n * @param ctx - The execution context\n * @param itemIndex - The index of the item to process\n * @param response - Optional engine response with previous tool calls\n * @returns ItemContext containing all item-specific state\n */\nexport async function prepareItemContext(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<ItemContext> {\n\tconst steps = buildSteps(response, itemIndex);\n\n\tconst input = getPromptInputByType({\n\t\tctx,\n\t\ti: itemIndex,\n\t\tinputKey: 'text',\n\t\tpromptTypeKey: 'promptType',\n\t});\n\tif (input === undefined) {\n\t\tthrow new NodeOperationError(ctx.getNode(), 'The \"text\" parameter is empty.');\n\t}\n\n\tconst outputParser = await getOptionalOutputParser(ctx, itemIndex);\n\tconst tools = await getTools(ctx, outputParser);\n\tconst options = ctx.getNodeParameter('options', itemIndex) as AgentOptions;\n\n\tif (options.enableStreaming === undefined) {\n\t\toptions.enableStreaming = true;\n\t}\n\n\t// Prepare the prompt messages and prompt template.\n\tconst messages = await prepareMessages(ctx, itemIndex, {\n\t\tsystemMessage: options.systemMessage,\n\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\toutputParser,\n\t});\n\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\treturn {\n\t\titemIndex,\n\t\tinput,\n\t\tsteps,\n\t\ttools,\n\t\tprompt,\n\t\toptions,\n\t\toutputParser,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAmC;AAGnC,6BAA8C;AAC9C,qBAAqC;AACrC,6BAAwC;AAGxC,oBAAyD;AAyBzD,eAAsB,mBACrB,KACA,WACA,UACuB;AACvB,QAAM,YAAQ,mCAAW,UAAU,SAAS;AAE5C,QAAM,YAAQ,qCAAqB;AAAA,IAClC;AAAA,IACA,GAAG;AAAA,IACH,UAAU;AAAA,IACV,eAAe;AAAA,EAChB,CAAC;AACD,MAAI,UAAU,QAAW;AACxB,UAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,gCAAgC;AAAA,EAC7E;AAEA,QAAM,eAAe,UAAM,gDAAwB,KAAK,SAAS;AACjE,QAAM,QAAQ,UAAM,wBAAS,KAAK,YAAY;AAC9C,QAAM,UAAU,IAAI,iBAAiB,WAAW,SAAS;AAEzD,MAAI,QAAQ,oBAAoB,QAAW;AAC1C,YAAQ,kBAAkB;AAAA,EAC3B;AAGA,QAAM,WAAW,UAAM,+BAAgB,KAAK,WAAW;AAAA,IACtD,eAAe,QAAQ;AAAA,IACvB,yBAAyB,QAAQ,2BAA2B;AAAA,IAC5D;AAAA,EACD,CAAC;AACD,QAAM,aAA6B,6BAAc,QAAQ;AAEzD,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/prepareItemContext.ts"],"sourcesContent":["import type { ChatPromptTemplate } from '@langchain/core/prompts';\nimport type { DynamicStructuredTool, Tool } from '@langchain/classic/tools';\nimport { NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions, EngineResponse } from 'n8n-workflow';\n\nimport { buildSteps, type ToolCallData } from '@utils/agent-execution';\nimport { getPromptInputByType } from '@utils/helpers';\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport { getTools, prepareMessages, preparePrompt } from '../../common';\nimport type { AgentOptions, RequestResponseMetadata } from '../types';\n\n/**\n * Context specific to a single item's processing\n */\nexport type ItemContext = {\n\titemIndex: number;\n\tinput: string;\n\tsteps: ToolCallData[];\n\ttools: Array<DynamicStructuredTool | Tool>;\n\tprompt: ChatPromptTemplate;\n\toptions: AgentOptions;\n\toutputParser: N8nOutputParser | undefined;\n};\n\n/**\n * Prepares the context for processing a single item.\n * This includes loading steps, input, tools, prompt, and options.\n *\n * @param ctx - The execution context\n * @param itemIndex - The index of the item to process\n * @param response - Optional engine response with previous tool calls\n * @returns ItemContext containing all item-specific state\n */\nexport async function prepareItemContext(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<ItemContext> {\n\tconst steps = buildSteps(response, itemIndex);\n\n\tconst input = getPromptInputByType({\n\t\tctx,\n\t\ti: itemIndex,\n\t\tinputKey: 'text',\n\t\tpromptTypeKey: 'promptType',\n\t});\n\tif (input === undefined) {\n\t\tthrow new NodeOperationError(ctx.getNode(), 'The \"text\" parameter is empty.');\n\t}\n\n\tconst outputParser = await getOptionalOutputParser(ctx, itemIndex);\n\tconst tools = await getTools(ctx, outputParser);\n\tconst options = ctx.getNodeParameter('options', itemIndex) as AgentOptions;\n\n\tif (options.enableStreaming === undefined) {\n\t\toptions.enableStreaming = true;\n\t}\n\n\t// Prepare the prompt messages and prompt template.\n\tconst messages = await prepareMessages(ctx, itemIndex, {\n\t\tsystemMessage: options.systemMessage,\n\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\toutputParser,\n\t});\n\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\treturn {\n\t\titemIndex,\n\t\tinput,\n\t\tsteps,\n\t\ttools,\n\t\tprompt,\n\t\toptions,\n\t\toutputParser,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAmC;AAGnC,6BAA8C;AAC9C,qBAAqC;AACrC,6BAAwC;AAGxC,oBAAyD;AAyBzD,eAAsB,mBACrB,KACA,WACA,UACuB;AACvB,QAAM,YAAQ,mCAAW,UAAU,SAAS;AAE5C,QAAM,YAAQ,qCAAqB;AAAA,IAClC;AAAA,IACA,GAAG;AAAA,IACH,UAAU;AAAA,IACV,eAAe;AAAA,EAChB,CAAC;AACD,MAAI,UAAU,QAAW;AACxB,UAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,gCAAgC;AAAA,EAC7E;AAEA,QAAM,eAAe,UAAM,gDAAwB,KAAK,SAAS;AACjE,QAAM,QAAQ,UAAM,wBAAS,KAAK,YAAY;AAC9C,QAAM,UAAU,IAAI,iBAAiB,WAAW,SAAS;AAEzD,MAAI,QAAQ,oBAAoB,QAAW;AAC1C,YAAQ,kBAAkB;AAAA,EAC3B;AAGA,QAAM,WAAW,UAAM,+BAAgB,KAAK,WAAW;AAAA,IACtD,eAAe,QAAQ;AAAA,IACvB,yBAAyB,QAAQ,2BAA2B;AAAA,IAC5D;AAAA,EACD,CAAC;AACD,QAAM,aAA6B,6BAAc,QAAQ;AAEzD,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;","names":[]}
@@ -46,14 +46,7 @@ async function runAgent(ctx, executor, itemContext, model, memory, response) {
46
46
  ...executeOptions
47
47
  }
48
48
  );
49
- const result = await (0, import_agent_execution.processEventStream)(
50
- ctx,
51
- eventStream,
52
- itemIndex,
53
- options.returnIntermediateSteps,
54
- memory,
55
- input
56
- );
49
+ const result = await (0, import_agent_execution.processEventStream)(ctx, eventStream, itemIndex);
57
50
  if (result.toolCalls && result.toolCalls.length > 0) {
58
51
  const actions = await (0, import_agent_execution.createEngineRequests)(result.toolCalls, itemIndex, tools);
59
52
  return {
@@ -61,6 +54,12 @@ async function runAgent(ctx, executor, itemContext, model, memory, response) {
61
54
  metadata: (0, import_buildResponseMetadata.buildResponseMetadata)(response, itemIndex)
62
55
  };
63
56
  }
57
+ if (memory && input && result?.output) {
58
+ await (0, import_agent_execution.saveToMemory)(input, result.output, memory, steps);
59
+ }
60
+ if (options.returnIntermediateSteps && steps.length > 0) {
61
+ result.intermediateSteps = steps;
62
+ }
64
63
  return result;
65
64
  } else {
66
65
  const chatHistory = await (0, import_agent_execution.loadMemory)(memory, model, options.maxTokensFromMemory);
@@ -70,14 +69,7 @@ async function runAgent(ctx, executor, itemContext, model, memory, response) {
70
69
  });
71
70
  if ("returnValues" in modelResponse) {
72
71
  if (memory && input && modelResponse.returnValues.output) {
73
- let fullOutput = modelResponse.returnValues.output;
74
- if (steps.length > 0) {
75
- const toolContext = steps.map(
76
- (step) => `Tool: ${step.action.tool}, Input: ${JSON.stringify(step.action.toolInput)}, Result: ${step.observation}`
77
- ).join("; ");
78
- fullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;
79
- }
80
- await (0, import_agent_execution.saveToMemory)(input, fullOutput, memory);
72
+ await (0, import_agent_execution.saveToMemory)(input, modelResponse.returnValues.output, memory, steps);
81
73
  }
82
74
  const result = { ...modelResponse.returnValues };
83
75
  if (options.returnIntermediateSteps && steps.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from 'langchain/agents';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport {\n\tloadMemory,\n\tprocessEventStream,\n\tcreateEngineRequests,\n\tsaveToMemory,\n} from '@utils/agent-execution';\n\nimport { SYSTEM_MESSAGE } from '../../prompt';\nimport type { AgentResult, RequestResponseMetadata } from '../types';\nimport { buildResponseMetadata } from './buildResponseMetadata';\nimport type { ItemContext } from './prepareItemContext';\n\ntype RunAgentResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Runs the agent for a single item, choosing between streaming or non-streaming execution.\n * Handles both regular execution and execution after tool calls.\n *\n * @param ctx - The execution context\n * @param executor - The agent runnable sequence\n * @param itemContext - Context for the current item\n * @param model - The chat model for token counting\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns AgentResult or engine request with tool calls\n */\nexport async function runAgent(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\texecutor: AgentRunnableSequence,\n\titemContext: ItemContext,\n\tmodel: BaseChatModel,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<RunAgentResult> {\n\tconst { itemIndex, input, steps, tools, options } = itemContext;\n\n\tconst invokeParams = {\n\t\tsteps,\n\t\tinput,\n\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\tformatting_instructions:\n\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t};\n\tconst executeOptions = { signal: ctx.getExecutionCancelSignal() };\n\n\t// Check if streaming is actually available\n\tconst isStreamingAvailable = 'isStreaming' in ctx ? ctx.isStreaming?.() : undefined;\n\n\tif (\n\t\t'isStreaming' in ctx &&\n\t\toptions.enableStreaming &&\n\t\tisStreamingAvailable &&\n\t\tctx.getNode().typeVersion >= 2.1\n\t) {\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\t\tconst eventStream = executor.streamEvents(\n\t\t\t{\n\t\t\t\t...invokeParams,\n\t\t\t\tchat_history: chatHistory,\n\t\t\t},\n\t\t\t{\n\t\t\t\tversion: 'v2',\n\t\t\t\t...executeOptions,\n\t\t\t},\n\t\t);\n\n\t\tconst result = await processEventStream(\n\t\t\tctx,\n\t\t\teventStream,\n\t\t\titemIndex,\n\t\t\toptions.returnIntermediateSteps,\n\t\t\tmemory,\n\t\t\tinput,\n\t\t);\n\n\t\t// If result contains tool calls, build the request object like the normal flow\n\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t\t};\n\t\t}\n\n\t\treturn result;\n\t} else {\n\t\t// Handle regular execution\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\n\t\tconst modelResponse = await executor.invoke({\n\t\t\t...invokeParams,\n\t\t\tchat_history: chatHistory,\n\t\t});\n\n\t\tif ('returnValues' in modelResponse) {\n\t\t\t// Save conversation to memory including any tool call context\n\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\t// If there were tool calls in this conversation, include them in the context\n\t\t\t\tlet fullOutput = modelResponse.returnValues.output as string;\n\n\t\t\t\tif (steps.length > 0) {\n\t\t\t\t\t// Include tool call information in the conversation context\n\t\t\t\t\tconst toolContext = steps\n\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t(step) =>\n\t\t\t\t\t\t\t\t`Tool: ${step.action.tool}, Input: ${JSON.stringify(step.action.toolInput)}, Result: ${step.observation}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('; ');\n\t\t\t\t\tfullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;\n\t\t\t\t}\n\n\t\t\t\tawait saveToMemory(input, fullOutput, memory);\n\t\t\t}\n\t\t\t// Include intermediate steps if requested\n\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// If response contains tool calls, we need to return this in the right format\n\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\treturn {\n\t\t\tactions,\n\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,6BAKO;AAEP,oBAA+B;AAE/B,mCAAsC;AAgBtC,eAAsB,SACrB,KACA,UACA,aACA,OACA,QACA,UAC0B;AAC1B,QAAM,EAAE,WAAW,OAAO,OAAO,OAAO,QAAQ,IAAI;AAEpD,QAAM,eAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ,iBAAiB;AAAA,IACzC,yBACC;AAAA,EACF;AACA,QAAM,iBAAiB,EAAE,QAAQ,IAAI,yBAAyB,EAAE;AAGhE,QAAM,uBAAuB,iBAAiB,MAAM,IAAI,cAAc,IAAI;AAE1E,MACC,iBAAiB,OACjB,QAAQ,mBACR,wBACA,IAAI,QAAQ,EAAE,eAAe,KAC5B;AACD,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAC/E,UAAM,cAAc,SAAS;AAAA,MAC5B;AAAA,QACC,GAAG;AAAA,QACH,cAAc;AAAA,MACf;AAAA,MACA;AAAA,QACC,SAAS;AAAA,QACT,GAAG;AAAA,MACJ;AAAA,IACD;AAEA,UAAM,SAAS,UAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACD;AAGA,QAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;AACpD,YAAM,UAAU,UAAM,6CAAqB,OAAO,WAAW,WAAW,KAAK;AAE7E,aAAO;AAAA,QACN;AAAA,QACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,MACpD;AAAA,IACD;AAEA,WAAO;AAAA,EACR,OAAO;AAEN,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAE/E,UAAM,gBAAgB,MAAM,SAAS,OAAO;AAAA,MAC3C,GAAG;AAAA,MACH,cAAc;AAAA,IACf,CAAC;AAED,QAAI,kBAAkB,eAAe;AAEpC,UAAI,UAAU,SAAS,cAAc,aAAa,QAAQ;AAEzD,YAAI,aAAa,cAAc,aAAa;AAE5C,YAAI,MAAM,SAAS,GAAG;AAErB,gBAAM,cAAc,MAClB;AAAA,YACA,CAAC,SACA,SAAS,KAAK,OAAO,IAAI,YAAY,KAAK,UAAU,KAAK,OAAO,SAAS,CAAC,aAAa,KAAK,WAAW;AAAA,UACzG,EACC,KAAK,IAAI;AACX,uBAAa,gBAAgB,WAAW,KAAK,UAAU;AAAA,QACxD;AAEA,kBAAM,qCAAa,OAAO,YAAY,MAAM;AAAA,MAC7C;AAEA,YAAM,SAAS,EAAE,GAAG,cAAc,aAAa;AAC/C,UAAI,QAAQ,2BAA2B,MAAM,SAAS,GAAG;AACxD,eAAO,oBAAoB;AAAA,MAC5B;AACA,aAAO;AAAA,IACR;AAGA,UAAM,UAAU,UAAM,6CAAqB,eAAe,WAAW,KAAK;AAE1E,WAAO;AAAA,MACN;AAAA,MACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,IACpD;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { AgentRunnableSequence } from '@langchain/classic/agents';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport type {\n\tIExecuteFunctions,\n\tISupplyDataFunctions,\n\tEngineResponse,\n\tEngineRequest,\n} from 'n8n-workflow';\n\nimport {\n\tloadMemory,\n\tprocessEventStream,\n\tcreateEngineRequests,\n\tsaveToMemory,\n} from '@utils/agent-execution';\n\nimport { SYSTEM_MESSAGE } from '../../prompt';\nimport type { AgentResult, RequestResponseMetadata } from '../types';\nimport { buildResponseMetadata } from './buildResponseMetadata';\nimport type { ItemContext } from './prepareItemContext';\n\ntype RunAgentResult = AgentResult | EngineRequest<RequestResponseMetadata>;\n/**\n * Runs the agent for a single item, choosing between streaming or non-streaming execution.\n * Handles both regular execution and execution after tool calls.\n *\n * @param ctx - The execution context\n * @param executor - The agent runnable sequence\n * @param itemContext - Context for the current item\n * @param model - The chat model for token counting\n * @param memory - Optional memory for conversation context\n * @param response - Optional engine response with previous tool calls\n * @returns AgentResult or engine request with tool calls\n */\nexport async function runAgent(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\texecutor: AgentRunnableSequence,\n\titemContext: ItemContext,\n\tmodel: BaseChatModel,\n\tmemory: BaseChatMemory | undefined,\n\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<RunAgentResult> {\n\tconst { itemIndex, input, steps, tools, options } = itemContext;\n\n\tconst invokeParams = {\n\t\tsteps,\n\t\tinput,\n\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\tformatting_instructions:\n\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t};\n\tconst executeOptions = { signal: ctx.getExecutionCancelSignal() };\n\n\t// Check if streaming is actually available\n\tconst isStreamingAvailable = 'isStreaming' in ctx ? ctx.isStreaming?.() : undefined;\n\n\tif (\n\t\t'isStreaming' in ctx &&\n\t\toptions.enableStreaming &&\n\t\tisStreamingAvailable &&\n\t\tctx.getNode().typeVersion >= 2.1\n\t) {\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\t\tconst eventStream = executor.streamEvents(\n\t\t\t{\n\t\t\t\t...invokeParams,\n\t\t\t\tchat_history: chatHistory,\n\t\t\t},\n\t\t\t{\n\t\t\t\tversion: 'v2',\n\t\t\t\t...executeOptions,\n\t\t\t},\n\t\t);\n\n\t\tconst result = await processEventStream(ctx, eventStream, itemIndex);\n\n\t\t// If result contains tool calls, build the request object like the normal flow\n\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t\t};\n\t\t}\n\t\t// Save conversation to memory including any tool call context\n\t\tif (memory && input && result?.output) {\n\t\t\tawait saveToMemory(input, result.output, memory, steps);\n\t\t}\n\n\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\tresult.intermediateSteps = steps;\n\t\t}\n\n\t\treturn result;\n\t} else {\n\t\t// Handle regular execution\n\t\tconst chatHistory = await loadMemory(memory, model, options.maxTokensFromMemory);\n\n\t\tconst modelResponse = await executor.invoke({\n\t\t\t...invokeParams,\n\t\t\tchat_history: chatHistory,\n\t\t});\n\n\t\tif ('returnValues' in modelResponse) {\n\t\t\t// Save conversation to memory including any tool call context\n\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\tawait saveToMemory(input, modelResponse.returnValues.output, memory, steps);\n\t\t\t}\n\t\t\t// Include intermediate steps if requested\n\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// If response contains tool calls, we need to return this in the right format\n\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\treturn {\n\t\t\tactions,\n\t\t\tmetadata: buildResponseMetadata(response, itemIndex),\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,6BAKO;AAEP,oBAA+B;AAE/B,mCAAsC;AAgBtC,eAAsB,SACrB,KACA,UACA,aACA,OACA,QACA,UAC0B;AAC1B,QAAM,EAAE,WAAW,OAAO,OAAO,OAAO,QAAQ,IAAI;AAEpD,QAAM,eAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA,gBAAgB,QAAQ,iBAAiB;AAAA,IACzC,yBACC;AAAA,EACF;AACA,QAAM,iBAAiB,EAAE,QAAQ,IAAI,yBAAyB,EAAE;AAGhE,QAAM,uBAAuB,iBAAiB,MAAM,IAAI,cAAc,IAAI;AAE1E,MACC,iBAAiB,OACjB,QAAQ,mBACR,wBACA,IAAI,QAAQ,EAAE,eAAe,KAC5B;AACD,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAC/E,UAAM,cAAc,SAAS;AAAA,MAC5B;AAAA,QACC,GAAG;AAAA,QACH,cAAc;AAAA,MACf;AAAA,MACA;AAAA,QACC,SAAS;AAAA,QACT,GAAG;AAAA,MACJ;AAAA,IACD;AAEA,UAAM,SAAS,UAAM,2CAAmB,KAAK,aAAa,SAAS;AAGnE,QAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;AACpD,YAAM,UAAU,UAAM,6CAAqB,OAAO,WAAW,WAAW,KAAK;AAE7E,aAAO;AAAA,QACN;AAAA,QACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,MACpD;AAAA,IACD;AAEA,QAAI,UAAU,SAAS,QAAQ,QAAQ;AACtC,gBAAM,qCAAa,OAAO,OAAO,QAAQ,QAAQ,KAAK;AAAA,IACvD;AAEA,QAAI,QAAQ,2BAA2B,MAAM,SAAS,GAAG;AACxD,aAAO,oBAAoB;AAAA,IAC5B;AAEA,WAAO;AAAA,EACR,OAAO;AAEN,UAAM,cAAc,UAAM,mCAAW,QAAQ,OAAO,QAAQ,mBAAmB;AAE/E,UAAM,gBAAgB,MAAM,SAAS,OAAO;AAAA,MAC3C,GAAG;AAAA,MACH,cAAc;AAAA,IACf,CAAC;AAED,QAAI,kBAAkB,eAAe;AAEpC,UAAI,UAAU,SAAS,cAAc,aAAa,QAAQ;AACzD,kBAAM,qCAAa,OAAO,cAAc,aAAa,QAAQ,QAAQ,KAAK;AAAA,MAC3E;AAEA,YAAM,SAAS,EAAE,GAAG,cAAc,aAAa;AAC/C,UAAI,QAAQ,2BAA2B,MAAM,SAAS,GAAG;AACxD,eAAO,oBAAoB;AAAA,MAC5B;AACA,aAAO;AAAA,IACR;AAGA,UAAM,UAAU,UAAM,6CAAqB,eAAe,WAAW,KAAK;AAE1E,WAAO;AAAA,MACN;AAAA,MACA,cAAU,oDAAsB,UAAU,SAAS;AAAA,IACpD;AAAA,EACD;AACD;","names":[]}
@@ -33,7 +33,7 @@ __export(common_exports, {
33
33
  module.exports = __toCommonJS(common_exports);
34
34
  var import_messages = require("@langchain/core/messages");
35
35
  var import_prompts = require("@langchain/core/prompts");
36
- var import_tools = require("langchain/tools");
36
+ var import_tools = require("@langchain/classic/tools");
37
37
  var import_n8n_workflow = require("n8n-workflow");
38
38
  var import_zod = require("zod");
39
39
  var import_helpers = require("../../../../../utils/helpers");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ToolsAgent/common.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, type BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport type { AgentAction, AgentFinish } from 'langchain/agents';\nimport type { ToolsAgentAction } from 'langchain/dist/agents/tool_calling/output_parser';\nimport type { BaseChatMemory } from 'langchain/memory';\nimport { DynamicStructuredTool, type Tool } from 'langchain/tools';\nimport { BINARY_ENCODING, jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions } from 'n8n-workflow';\nimport type { ZodObject } from 'zod';\nimport { z } from 'zod';\n\nimport { isChatInstance, getConnectedTools } from '@utils/helpers';\nimport { type N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\n/* -----------------------------------------------------------\n Output Parser Helper\n----------------------------------------------------------- */\n/**\n * Retrieve the output parser schema.\n * If the parser does not return a valid schema, default to a schema with a single text field.\n */\nexport function getOutputParserSchema(\n\toutputParser: N8nOutputParser,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ZodObject<any, any, any, any> {\n\tconst schema =\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t(outputParser.getSchema() as ZodObject<any, any, any, any>) ?? z.object({ text: z.string() });\n\treturn schema;\n}\n\n/* -----------------------------------------------------------\n Binary Data Helpers\n----------------------------------------------------------- */\nfunction isTextFile(mimeType: string): boolean {\n\treturn (\n\t\tmimeType.startsWith('text/') ||\n\t\tmimeType === 'application/json' ||\n\t\tmimeType === 'application/xml' ||\n\t\tmimeType === 'application/csv' ||\n\t\tmimeType === 'application/x-yaml' ||\n\t\tmimeType === 'application/yaml'\n\t);\n}\n\nfunction isImageFile(mimeType: string): boolean {\n\treturn mimeType.startsWith('image/');\n}\n\n/**\n * Extracts binary messages (images and text files) from the input data.\n * When operating in filesystem mode, the binary stream is first converted to a buffer.\n *\n * Images are converted to base64 data URLs.\n * Text files are read as UTF-8 text and included in the message content.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @returns A HumanMessage containing the binary messages (images and text files).\n */\nexport async function extractBinaryMessages(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n): Promise<HumanMessage> {\n\tconst binaryData = ctx.getInputData()?.[itemIndex]?.binary ?? {};\n\tconst binaryMessages = await Promise.all(\n\t\tObject.values(binaryData)\n\t\t\t// select only the files we can process\n\t\t\t.filter((data) => isImageFile(data.mimeType) || isTextFile(data.mimeType))\n\t\t\t.map(async (data) => {\n\t\t\t\t// Handle images\n\t\t\t\tif (isImageFile(data.mimeType)) {\n\t\t\t\t\tlet binaryUrlString: string;\n\n\t\t\t\t\t// In filesystem mode we need to get binary stream by id before converting it to buffer\n\t\t\t\t\tif (data.id) {\n\t\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbinaryUrlString = `data:${data.mimeType};base64,${Buffer.from(binaryBuffer).toString(\n\t\t\t\t\t\t\tBINARY_ENCODING,\n\t\t\t\t\t\t)}`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbinaryUrlString = data.data.includes('base64')\n\t\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t\t: `data:${data.mimeType};base64,${data.data}`;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'image_url',\n\t\t\t\t\t\timage_url: {\n\t\t\t\t\t\t\turl: binaryUrlString,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// Handle text files\n\t\t\t\telse {\n\t\t\t\t\tlet textContent: string;\n\t\t\t\t\tif (data.id) {\n\t\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t\t);\n\t\t\t\t\t\ttextContent = binaryBuffer.toString('utf-8');\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Data might be base64 encoded with or without data URL prefix\n\t\t\t\t\t\tif (data.data.includes('base64,')) {\n\t\t\t\t\t\t\tconst base64Data = data.data.split('base64,')[1];\n\t\t\t\t\t\t\ttextContent = Buffer.from(base64Data, 'base64').toString('utf-8');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Default: binary data is base64-encoded without prefix\n\t\t\t\t\t\t\ttextContent = Buffer.from(data.data, 'base64').toString('utf-8');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\ttext: `File: ${data.fileName ?? 'attachment'}\\nContent:\\n${textContent}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}),\n\t);\n\treturn new HumanMessage({\n\t\tcontent: [...binaryMessages],\n\t});\n}\n\n/* -----------------------------------------------------------\n Agent Output Format Helpers\n----------------------------------------------------------- */\n/**\n * Fixes empty content messages in agent steps.\n *\n * This function is necessary when using RunnableSequence.from in LangChain.\n * If a tool doesn't have any arguments, LangChain returns input: '' (empty string).\n * This can throw an error for some providers (like Anthropic) which expect the input to always be an object.\n * This function replaces empty string inputs with empty objects to prevent such errors.\n *\n * @param steps - The agent steps to fix\n * @returns The fixed agent steps\n */\nexport function fixEmptyContentMessage(\n\tsteps: AgentFinish | ToolsAgentAction[],\n): AgentFinish | ToolsAgentAction[] {\n\tif (!Array.isArray(steps)) return steps;\n\n\tsteps.forEach((step) => {\n\t\tif ('messageLog' in step && step.messageLog !== undefined) {\n\t\t\tif (Array.isArray(step.messageLog)) {\n\t\t\t\tstep.messageLog.forEach((message: BaseMessage) => {\n\t\t\t\t\tif ('content' in message && Array.isArray(message.content)) {\n\t\t\t\t\t\t(message.content as Array<{ input?: string | object }>).forEach((content) => {\n\t\t\t\t\t\t\tif (content.input === '') {\n\t\t\t\t\t\t\t\tcontent.input = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn steps;\n}\n\n/**\n * Ensures consistent handling of outputs regardless of the model used,\n * providing a unified output format for further processing.\n *\n * This method is necessary to handle different output formats from various language models.\n * Specifically, it checks if the agent step is the final step (contains returnValues) and determines\n * if the output is a simple string (e.g., from OpenAI models) or an array of outputs (e.g., from Anthropic models).\n *\n * Examples:\n * 1. Anthropic model output:\n * ```json\n * {\n * \"output\": [\n * {\n * \"index\": 0,\n * \"type\": \"text\",\n * \"text\": \"The result of the calculation is approximately 1001.8166...\"\n * }\n * ]\n * }\n *```\n * 2. OpenAI model output:\n * ```json\n * {\n * \"output\": \"The result of the calculation is approximately 1001.82...\"\n * }\n * ```\n *\n * @param steps - The agent finish or agent action steps.\n * @returns The modified agent finish steps or the original steps.\n */\nexport function handleAgentFinishOutput(\n\tsteps: AgentFinish | AgentAction[],\n): AgentFinish | AgentAction[] {\n\ttype AgentMultiOutputFinish = AgentFinish & {\n\t\treturnValues: { output: Array<{ text: string; type: string; index: number }> };\n\t};\n\tconst agentFinishSteps = steps as AgentMultiOutputFinish | AgentFinish;\n\n\tif (agentFinishSteps.returnValues) {\n\t\tconst isMultiOutput = Array.isArray(agentFinishSteps.returnValues?.output);\n\t\tif (isMultiOutput) {\n\t\t\tconst multiOutputSteps = agentFinishSteps.returnValues.output as Array<{\n\t\t\t\tindex: number;\n\t\t\t\ttype: string;\n\t\t\t\ttext?: string;\n\t\t\t\tthinking?: string;\n\t\t\t}>;\n\n\t\t\t// Filter out thinking blocks and join text blocks\n\t\t\tconst textOutputs = multiOutputSteps\n\t\t\t\t.filter((output) => output.type === 'text' && output.text)\n\t\t\t\t.map((output) => output.text)\n\t\t\t\t.join('\\n')\n\t\t\t\t.trim();\n\n\t\t\tif (textOutputs) {\n\t\t\t\tagentFinishSteps.returnValues.output = textOutputs;\n\t\t\t} else {\n\t\t\t\tconst thinkingOutputs = multiOutputSteps\n\t\t\t\t\t.filter((output) => output.type === 'thinking' && output.thinking)\n\t\t\t\t\t.map((output) => output.thinking)\n\t\t\t\t\t.join('\\n')\n\t\t\t\t\t.trim();\n\n\t\t\t\tif (thinkingOutputs) {\n\t\t\t\t\tagentFinishSteps.returnValues.output = thinkingOutputs;\n\t\t\t\t} else {\n\t\t\t\t\t// no output was found\n\t\t\t\t\tagentFinishSteps.returnValues.output = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn agentFinishSteps;\n\t\t}\n\t}\n\n\treturn agentFinishSteps;\n}\n\n/**\n * Wraps the parsed output so that it can be stored in memory.\n * If memory is connected, the output is stringified.\n *\n * @param output - The parsed output object\n * @param memory - The connected memory (if any)\n * @returns The formatted output object\n */\nexport function handleParsedStepOutput(\n\toutput: Record<string, unknown>,\n\tmemory?: BaseChatMemory,\n): { returnValues: Record<string, unknown>; log: string } {\n\treturn {\n\t\treturnValues: memory ? { output: JSON.stringify(output) } : output,\n\t\tlog: 'Final response formatted',\n\t};\n}\n\n/**\n * Parses agent steps using the provided output parser.\n * If the agent used the 'format_final_json_response' tool, the output is parsed accordingly.\n *\n * @param steps - The agent finish or action steps\n * @param outputParser - The output parser (if defined)\n * @param memory - The connected memory (if any)\n * @returns The parsed steps with the final output\n */\nexport const getAgentStepsParser =\n\t(outputParser?: N8nOutputParser, memory?: BaseChatMemory) =>\n\tasync (steps: AgentFinish | AgentAction[]): Promise<AgentFinish | AgentAction[]> => {\n\t\t// Check if the steps contain the 'format_final_json_response' tool invocation.\n\t\tif (Array.isArray(steps)) {\n\t\t\tconst responseParserTool = steps.find((step) => step.tool === 'format_final_json_response');\n\t\t\tif (responseParserTool && outputParser) {\n\t\t\t\tconst toolInput = responseParserTool.toolInput;\n\t\t\t\t// Ensure the tool input is a string\n\t\t\t\tconst parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;\n\t\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, if the steps contain a returnValues field, try to parse them manually.\n\t\tif (outputParser && typeof steps === 'object' && (steps as AgentFinish).returnValues) {\n\t\t\tconst finalResponse = (steps as AgentFinish).returnValues;\n\t\t\tlet parserInput: string;\n\n\t\t\tif (finalResponse instanceof Object) {\n\t\t\t\tif ('output' in finalResponse) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst parsedOutput = jsonParse<Record<string, unknown>>(finalResponse.output);\n\t\t\t\t\t\t// Check if the parsed output already has the expected structure\n\t\t\t\t\t\t// If it already has { output: ... }, use it as-is to avoid double wrapping\n\t\t\t\t\t\t// Otherwise, wrap it in { output: ... } as expected by the parser\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tparsedOutput !== null &&\n\t\t\t\t\t\t\ttypeof parsedOutput === 'object' &&\n\t\t\t\t\t\t\t'output' in parsedOutput &&\n\t\t\t\t\t\t\tObject.keys(parsedOutput).length === 1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Already has the expected structure, use as-is\n\t\t\t\t\t\t\tparserInput = JSON.stringify(parsedOutput);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Needs wrapping for the parser\n\t\t\t\t\t\t\tparserInput = JSON.stringify({ output: parsedOutput });\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Fallback to the raw output if parsing fails.\n\t\t\t\t\t\tparserInput = finalResponse.output;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the output is not an object, we will stringify it as it is\n\t\t\t\t\tparserInput = JSON.stringify(finalResponse);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparserInput = finalResponse;\n\t\t\t}\n\n\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t}\n\n\t\treturn handleAgentFinishOutput(steps);\n\t};\n\n/* -----------------------------------------------------------\n Agent Setup Helpers\n----------------------------------------------------------- */\n/**\n * Retrieves the language model from the input connection.\n * Throws an error if the model is not a valid chat instance or does not support tools.\n *\n * @param ctx - The execution context\n * @returns The validated chat model\n */\nexport async function getChatModel(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\tindex: number = 0,\n): Promise<BaseChatModel | undefined> {\n\tconst connectedModels = await ctx.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0);\n\n\tlet model;\n\n\tif (Array.isArray(connectedModels) && index !== undefined) {\n\t\tif (connectedModels.length <= index) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// We get the models in reversed order from the workflow so we need to reverse them to match the right index\n\t\tconst reversedModels = [...connectedModels].reverse();\n\t\tmodel = reversedModels[index] as BaseChatModel;\n\t} else {\n\t\tmodel = connectedModels as BaseChatModel;\n\t}\n\n\tif (!isChatInstance(model) || !model.bindTools) {\n\t\tthrow new NodeOperationError(\n\t\t\tctx.getNode(),\n\t\t\t'Tools Agent requires Chat Model which supports Tools calling',\n\t\t);\n\t}\n\treturn model;\n}\n\n/**\n * Retrieves the memory instance from the input connection if it is connected\n *\n * @param ctx - The execution context\n * @returns The connected memory (if any)\n */\nexport async function getOptionalMemory(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<BaseChatMemory | undefined> {\n\treturn (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t| BaseChatMemory\n\t\t| undefined;\n}\n\n/**\n * Retrieves the connected tools and (if an output parser is defined)\n * appends a structured output parser tool.\n *\n * @param ctx - The execution context\n * @param outputParser - The optional output parser\n * @returns The array of connected tools\n */\nexport async function getTools(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\toutputParser?: N8nOutputParser,\n): Promise<Array<DynamicStructuredTool | Tool>> {\n\tconst tools = (await getConnectedTools(ctx, true, false)) as Array<DynamicStructuredTool | Tool>;\n\n\t// If an output parser is available, create a dynamic tool to validate the final output.\n\tif (outputParser) {\n\t\tconst schema = getOutputParserSchema(outputParser);\n\t\tconst structuredOutputParserTool = new DynamicStructuredTool({\n\t\t\tschema,\n\t\t\tname: 'format_final_json_response',\n\t\t\tdescription:\n\t\t\t\t'Use this tool to format your final response to the user in a structured JSON format. This tool validates your output against a schema to ensure it meets the required format. ONLY use this tool when you have completed all necessary reasoning and are ready to provide your final answer. Do not use this tool for intermediate steps or for asking questions. The output from this tool will be directly returned to the user.',\n\t\t\t// We do not use a function here because we intercept the output with the parser.\n\t\t\tfunc: async () => '',\n\t\t});\n\t\ttools.push(structuredOutputParserTool);\n\t}\n\treturn tools;\n}\n\n/**\n * Prepares the prompt messages for the agent.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @param options - Options containing systemMessage and other parameters\n * @returns The array of prompt messages\n */\nexport async function prepareMessages(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\toptions: {\n\t\tsystemMessage?: string;\n\t\tpassthroughBinaryImages?: boolean;\n\t\toutputParser?: N8nOutputParser;\n\t},\n): Promise<BaseMessagePromptTemplateLike[]> {\n\tconst useSystemMessage = options.systemMessage ?? ctx.getNode().typeVersion < 1.9;\n\n\tconst messages: BaseMessagePromptTemplateLike[] = [];\n\n\tif (useSystemMessage) {\n\t\tmessages.push([\n\t\t\t'system',\n\t\t\t`{system_message}${options.outputParser ? '\\n\\n{formatting_instructions}' : ''}`,\n\t\t]);\n\t} else if (options.outputParser) {\n\t\tmessages.push(['system', '{formatting_instructions}']);\n\t}\n\n\tmessages.push(['placeholder', '{chat_history}'], ['human', '{input}']);\n\n\t// If there is binary data and the node option permits it, add a binary message\n\tconst hasBinaryData = ctx.getInputData()?.[itemIndex]?.binary !== undefined;\n\tif (hasBinaryData && options.passthroughBinaryImages) {\n\t\tconst binaryMessage = await extractBinaryMessages(ctx, itemIndex);\n\t\tif (binaryMessage.content.length !== 0) {\n\t\t\tmessages.push(binaryMessage);\n\t\t} else {\n\t\t\tctx.logger.debug('Not attaching binary message, since its content was empty');\n\t\t}\n\t}\n\n\t// We add the agent scratchpad last, so that the agent will not run in loops\n\t// by adding binary messages between each interaction\n\tmessages.push(['placeholder', '{agent_scratchpad}']);\n\treturn messages;\n}\n\n/**\n * Creates the chat prompt from messages.\n *\n * @param messages - The messages array\n * @returns The ChatPromptTemplate instance\n */\nexport function preparePrompt(messages: BaseMessagePromptTemplateLike[]): ChatPromptTemplate {\n\treturn ChatPromptTemplate.fromMessages(messages);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/ToolsAgent/common.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, type BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport type { AgentAction, AgentFinish } from '@langchain/classic/agents';\nimport type { ToolsAgentAction } from '@langchain/classic/dist/agents/tool_calling/output_parser';\nimport type { BaseChatMemory } from '@langchain/classic/memory';\nimport { DynamicStructuredTool, type Tool } from '@langchain/classic/tools';\nimport { BINARY_ENCODING, jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, ISupplyDataFunctions } from 'n8n-workflow';\nimport type { ZodObject } from 'zod';\nimport { z } from 'zod';\n\nimport { isChatInstance, getConnectedTools } from '@utils/helpers';\nimport { type N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\n/* -----------------------------------------------------------\n Output Parser Helper\n----------------------------------------------------------- */\n/**\n * Retrieve the output parser schema.\n * If the parser does not return a valid schema, default to a schema with a single text field.\n */\nexport function getOutputParserSchema(\n\toutputParser: N8nOutputParser,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ZodObject<any, any, any, any> {\n\tconst schema =\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t(outputParser.getSchema() as ZodObject<any, any, any, any>) ?? z.object({ text: z.string() });\n\treturn schema;\n}\n\n/* -----------------------------------------------------------\n Binary Data Helpers\n----------------------------------------------------------- */\nfunction isTextFile(mimeType: string): boolean {\n\treturn (\n\t\tmimeType.startsWith('text/') ||\n\t\tmimeType === 'application/json' ||\n\t\tmimeType === 'application/xml' ||\n\t\tmimeType === 'application/csv' ||\n\t\tmimeType === 'application/x-yaml' ||\n\t\tmimeType === 'application/yaml'\n\t);\n}\n\nfunction isImageFile(mimeType: string): boolean {\n\treturn mimeType.startsWith('image/');\n}\n\n/**\n * Extracts binary messages (images and text files) from the input data.\n * When operating in filesystem mode, the binary stream is first converted to a buffer.\n *\n * Images are converted to base64 data URLs.\n * Text files are read as UTF-8 text and included in the message content.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @returns A HumanMessage containing the binary messages (images and text files).\n */\nexport async function extractBinaryMessages(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n): Promise<HumanMessage> {\n\tconst binaryData = ctx.getInputData()?.[itemIndex]?.binary ?? {};\n\tconst binaryMessages = await Promise.all(\n\t\tObject.values(binaryData)\n\t\t\t// select only the files we can process\n\t\t\t.filter((data) => isImageFile(data.mimeType) || isTextFile(data.mimeType))\n\t\t\t.map(async (data) => {\n\t\t\t\t// Handle images\n\t\t\t\tif (isImageFile(data.mimeType)) {\n\t\t\t\t\tlet binaryUrlString: string;\n\n\t\t\t\t\t// In filesystem mode we need to get binary stream by id before converting it to buffer\n\t\t\t\t\tif (data.id) {\n\t\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbinaryUrlString = `data:${data.mimeType};base64,${Buffer.from(binaryBuffer).toString(\n\t\t\t\t\t\t\tBINARY_ENCODING,\n\t\t\t\t\t\t)}`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbinaryUrlString = data.data.includes('base64')\n\t\t\t\t\t\t\t? data.data\n\t\t\t\t\t\t\t: `data:${data.mimeType};base64,${data.data}`;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'image_url',\n\t\t\t\t\t\timage_url: {\n\t\t\t\t\t\t\turl: binaryUrlString,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// Handle text files\n\t\t\t\telse {\n\t\t\t\t\tlet textContent: string;\n\t\t\t\t\tif (data.id) {\n\t\t\t\t\t\tconst binaryBuffer = await ctx.helpers.binaryToBuffer(\n\t\t\t\t\t\t\tawait ctx.helpers.getBinaryStream(data.id),\n\t\t\t\t\t\t);\n\t\t\t\t\t\ttextContent = binaryBuffer.toString('utf-8');\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Data might be base64 encoded with or without data URL prefix\n\t\t\t\t\t\tif (data.data.includes('base64,')) {\n\t\t\t\t\t\t\tconst base64Data = data.data.split('base64,')[1];\n\t\t\t\t\t\t\ttextContent = Buffer.from(base64Data, 'base64').toString('utf-8');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Default: binary data is base64-encoded without prefix\n\t\t\t\t\t\t\ttextContent = Buffer.from(data.data, 'base64').toString('utf-8');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\ttext: `File: ${data.fileName ?? 'attachment'}\\nContent:\\n${textContent}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}),\n\t);\n\treturn new HumanMessage({\n\t\tcontent: [...binaryMessages],\n\t});\n}\n\n/* -----------------------------------------------------------\n Agent Output Format Helpers\n----------------------------------------------------------- */\n/**\n * Fixes empty content messages in agent steps.\n *\n * This function is necessary when using RunnableSequence.from in LangChain.\n * If a tool doesn't have any arguments, LangChain returns input: '' (empty string).\n * This can throw an error for some providers (like Anthropic) which expect the input to always be an object.\n * This function replaces empty string inputs with empty objects to prevent such errors.\n *\n * @param steps - The agent steps to fix\n * @returns The fixed agent steps\n */\nexport function fixEmptyContentMessage(\n\tsteps: AgentFinish | ToolsAgentAction[],\n): AgentFinish | ToolsAgentAction[] {\n\tif (!Array.isArray(steps)) return steps;\n\n\tsteps.forEach((step) => {\n\t\tif ('messageLog' in step && step.messageLog !== undefined) {\n\t\t\tif (Array.isArray(step.messageLog)) {\n\t\t\t\tstep.messageLog.forEach((message: BaseMessage) => {\n\t\t\t\t\tif ('content' in message && Array.isArray(message.content)) {\n\t\t\t\t\t\t(message.content as Array<{ input?: string | object }>).forEach((content) => {\n\t\t\t\t\t\t\tif (content.input === '') {\n\t\t\t\t\t\t\t\tcontent.input = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn steps;\n}\n\n/**\n * Ensures consistent handling of outputs regardless of the model used,\n * providing a unified output format for further processing.\n *\n * This method is necessary to handle different output formats from various language models.\n * Specifically, it checks if the agent step is the final step (contains returnValues) and determines\n * if the output is a simple string (e.g., from OpenAI models) or an array of outputs (e.g., from Anthropic models).\n *\n * Examples:\n * 1. Anthropic model output:\n * ```json\n * {\n * \"output\": [\n * {\n * \"index\": 0,\n * \"type\": \"text\",\n * \"text\": \"The result of the calculation is approximately 1001.8166...\"\n * }\n * ]\n * }\n *```\n * 2. OpenAI model output:\n * ```json\n * {\n * \"output\": \"The result of the calculation is approximately 1001.82...\"\n * }\n * ```\n *\n * @param steps - The agent finish or agent action steps.\n * @returns The modified agent finish steps or the original steps.\n */\nexport function handleAgentFinishOutput(\n\tsteps: AgentFinish | AgentAction[],\n): AgentFinish | AgentAction[] {\n\ttype AgentMultiOutputFinish = AgentFinish & {\n\t\treturnValues: { output: Array<{ text: string; type: string; index: number }> };\n\t};\n\tconst agentFinishSteps = steps as AgentMultiOutputFinish | AgentFinish;\n\n\tif (agentFinishSteps.returnValues) {\n\t\tconst isMultiOutput = Array.isArray(agentFinishSteps.returnValues?.output);\n\t\tif (isMultiOutput) {\n\t\t\tconst multiOutputSteps = agentFinishSteps.returnValues.output as Array<{\n\t\t\t\tindex: number;\n\t\t\t\ttype: string;\n\t\t\t\ttext?: string;\n\t\t\t\tthinking?: string;\n\t\t\t}>;\n\n\t\t\t// Filter out thinking blocks and join text blocks\n\t\t\tconst textOutputs = multiOutputSteps\n\t\t\t\t.filter((output) => output.type === 'text' && output.text)\n\t\t\t\t.map((output) => output.text)\n\t\t\t\t.join('\\n')\n\t\t\t\t.trim();\n\n\t\t\tif (textOutputs) {\n\t\t\t\tagentFinishSteps.returnValues.output = textOutputs;\n\t\t\t} else {\n\t\t\t\tconst thinkingOutputs = multiOutputSteps\n\t\t\t\t\t.filter((output) => output.type === 'thinking' && output.thinking)\n\t\t\t\t\t.map((output) => output.thinking)\n\t\t\t\t\t.join('\\n')\n\t\t\t\t\t.trim();\n\n\t\t\t\tif (thinkingOutputs) {\n\t\t\t\t\tagentFinishSteps.returnValues.output = thinkingOutputs;\n\t\t\t\t} else {\n\t\t\t\t\t// no output was found\n\t\t\t\t\tagentFinishSteps.returnValues.output = '';\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn agentFinishSteps;\n\t\t}\n\t}\n\n\treturn agentFinishSteps;\n}\n\n/**\n * Wraps the parsed output so that it can be stored in memory.\n * If memory is connected, the output is stringified.\n *\n * @param output - The parsed output object\n * @param memory - The connected memory (if any)\n * @returns The formatted output object\n */\nexport function handleParsedStepOutput(\n\toutput: Record<string, unknown>,\n\tmemory?: BaseChatMemory,\n): { returnValues: Record<string, unknown>; log: string } {\n\treturn {\n\t\treturnValues: memory ? { output: JSON.stringify(output) } : output,\n\t\tlog: 'Final response formatted',\n\t};\n}\n\n/**\n * Parses agent steps using the provided output parser.\n * If the agent used the 'format_final_json_response' tool, the output is parsed accordingly.\n *\n * @param steps - The agent finish or action steps\n * @param outputParser - The output parser (if defined)\n * @param memory - The connected memory (if any)\n * @returns The parsed steps with the final output\n */\nexport const getAgentStepsParser =\n\t(outputParser?: N8nOutputParser, memory?: BaseChatMemory) =>\n\tasync (steps: AgentFinish | AgentAction[]): Promise<AgentFinish | AgentAction[]> => {\n\t\t// Check if the steps contain the 'format_final_json_response' tool invocation.\n\t\tif (Array.isArray(steps)) {\n\t\t\tconst responseParserTool = steps.find((step) => step.tool === 'format_final_json_response');\n\t\t\tif (responseParserTool && outputParser) {\n\t\t\t\tconst toolInput = responseParserTool.toolInput;\n\t\t\t\t// Ensure the tool input is a string\n\t\t\t\tconst parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;\n\t\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, if the steps contain a returnValues field, try to parse them manually.\n\t\tif (outputParser && typeof steps === 'object' && (steps as AgentFinish).returnValues) {\n\t\t\tconst finalResponse = (steps as AgentFinish).returnValues;\n\t\t\tlet parserInput: string;\n\n\t\t\tif (finalResponse instanceof Object) {\n\t\t\t\tif ('output' in finalResponse) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst parsedOutput = jsonParse<Record<string, unknown>>(finalResponse.output);\n\t\t\t\t\t\t// Check if the parsed output already has the expected structure\n\t\t\t\t\t\t// If it already has { output: ... }, use it as-is to avoid double wrapping\n\t\t\t\t\t\t// Otherwise, wrap it in { output: ... } as expected by the parser\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tparsedOutput !== null &&\n\t\t\t\t\t\t\ttypeof parsedOutput === 'object' &&\n\t\t\t\t\t\t\t'output' in parsedOutput &&\n\t\t\t\t\t\t\tObject.keys(parsedOutput).length === 1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Already has the expected structure, use as-is\n\t\t\t\t\t\t\tparserInput = JSON.stringify(parsedOutput);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Needs wrapping for the parser\n\t\t\t\t\t\t\tparserInput = JSON.stringify({ output: parsedOutput });\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Fallback to the raw output if parsing fails.\n\t\t\t\t\t\tparserInput = finalResponse.output;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the output is not an object, we will stringify it as it is\n\t\t\t\t\tparserInput = JSON.stringify(finalResponse);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparserInput = finalResponse;\n\t\t\t}\n\n\t\t\tconst returnValues = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\treturn handleParsedStepOutput(returnValues, memory);\n\t\t}\n\n\t\treturn handleAgentFinishOutput(steps);\n\t};\n\n/* -----------------------------------------------------------\n Agent Setup Helpers\n----------------------------------------------------------- */\n/**\n * Retrieves the language model from the input connection.\n * Throws an error if the model is not a valid chat instance or does not support tools.\n *\n * @param ctx - The execution context\n * @returns The validated chat model\n */\nexport async function getChatModel(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\tindex: number = 0,\n): Promise<BaseChatModel | undefined> {\n\tconst connectedModels = await ctx.getInputConnectionData(NodeConnectionTypes.AiLanguageModel, 0);\n\n\tlet model;\n\n\tif (Array.isArray(connectedModels) && index !== undefined) {\n\t\tif (connectedModels.length <= index) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// We get the models in reversed order from the workflow so we need to reverse them to match the right index\n\t\tconst reversedModels = [...connectedModels].reverse();\n\t\tmodel = reversedModels[index] as BaseChatModel;\n\t} else {\n\t\tmodel = connectedModels as BaseChatModel;\n\t}\n\n\tif (!isChatInstance(model) || !model.bindTools) {\n\t\tthrow new NodeOperationError(\n\t\t\tctx.getNode(),\n\t\t\t'Tools Agent requires Chat Model which supports Tools calling',\n\t\t);\n\t}\n\treturn model;\n}\n\n/**\n * Retrieves the memory instance from the input connection if it is connected\n *\n * @param ctx - The execution context\n * @returns The connected memory (if any)\n */\nexport async function getOptionalMemory(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n): Promise<BaseChatMemory | undefined> {\n\treturn (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t| BaseChatMemory\n\t\t| undefined;\n}\n\n/**\n * Retrieves the connected tools and (if an output parser is defined)\n * appends a structured output parser tool.\n *\n * @param ctx - The execution context\n * @param outputParser - The optional output parser\n * @returns The array of connected tools\n */\nexport async function getTools(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\toutputParser?: N8nOutputParser,\n): Promise<Array<DynamicStructuredTool | Tool>> {\n\tconst tools = (await getConnectedTools(ctx, true, false)) as Array<DynamicStructuredTool | Tool>;\n\n\t// If an output parser is available, create a dynamic tool to validate the final output.\n\tif (outputParser) {\n\t\tconst schema = getOutputParserSchema(outputParser);\n\t\tconst structuredOutputParserTool = new DynamicStructuredTool({\n\t\t\tschema,\n\t\t\tname: 'format_final_json_response',\n\t\t\tdescription:\n\t\t\t\t'Use this tool to format your final response to the user in a structured JSON format. This tool validates your output against a schema to ensure it meets the required format. ONLY use this tool when you have completed all necessary reasoning and are ready to provide your final answer. Do not use this tool for intermediate steps or for asking questions. The output from this tool will be directly returned to the user.',\n\t\t\t// We do not use a function here because we intercept the output with the parser.\n\t\t\tfunc: async () => '',\n\t\t});\n\t\ttools.push(structuredOutputParserTool);\n\t}\n\treturn tools;\n}\n\n/**\n * Prepares the prompt messages for the agent.\n *\n * @param ctx - The execution context\n * @param itemIndex - The current item index\n * @param options - Options containing systemMessage and other parameters\n * @returns The array of prompt messages\n */\nexport async function prepareMessages(\n\tctx: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\toptions: {\n\t\tsystemMessage?: string;\n\t\tpassthroughBinaryImages?: boolean;\n\t\toutputParser?: N8nOutputParser;\n\t},\n): Promise<BaseMessagePromptTemplateLike[]> {\n\tconst useSystemMessage = options.systemMessage ?? ctx.getNode().typeVersion < 1.9;\n\n\tconst messages: BaseMessagePromptTemplateLike[] = [];\n\n\tif (useSystemMessage) {\n\t\tmessages.push([\n\t\t\t'system',\n\t\t\t`{system_message}${options.outputParser ? '\\n\\n{formatting_instructions}' : ''}`,\n\t\t]);\n\t} else if (options.outputParser) {\n\t\tmessages.push(['system', '{formatting_instructions}']);\n\t}\n\n\tmessages.push(['placeholder', '{chat_history}'], ['human', '{input}']);\n\n\t// If there is binary data and the node option permits it, add a binary message\n\tconst hasBinaryData = ctx.getInputData()?.[itemIndex]?.binary !== undefined;\n\tif (hasBinaryData && options.passthroughBinaryImages) {\n\t\tconst binaryMessage = await extractBinaryMessages(ctx, itemIndex);\n\t\tif (binaryMessage.content.length !== 0) {\n\t\t\tmessages.push(binaryMessage);\n\t\t} else {\n\t\t\tctx.logger.debug('Not attaching binary message, since its content was empty');\n\t\t}\n\t}\n\n\t// We add the agent scratchpad last, so that the agent will not run in loops\n\t// by adding binary messages between each interaction\n\tmessages.push(['placeholder', '{agent_scratchpad}']);\n\treturn messages;\n}\n\n/**\n * Creates the chat prompt from messages.\n *\n * @param messages - The messages array\n * @returns The ChatPromptTemplate instance\n */\nexport function preparePrompt(messages: BaseMessagePromptTemplateLike[]): ChatPromptTemplate {\n\treturn ChatPromptTemplate.fromMessages(messages);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA6B;AAE7B,qBAAuE;AAIvE,mBAAiD;AACjD,0BAAoF;AAGpF,iBAAkB;AAElB,qBAAkD;AAU3C,SAAS,sBACf,cAEgC;AAChC,QAAM;AAAA;AAAA,IAEJ,aAAa,UAAU,KAAuC,aAAE,OAAO,EAAE,MAAM,aAAE,OAAO,EAAE,CAAC;AAAA;AAC7F,SAAO;AACR;AAKA,SAAS,WAAW,UAA2B;AAC9C,SACC,SAAS,WAAW,OAAO,KAC3B,aAAa,sBACb,aAAa,qBACb,aAAa,qBACb,aAAa,wBACb,aAAa;AAEf;AAEA,SAAS,YAAY,UAA2B;AAC/C,SAAO,SAAS,WAAW,QAAQ;AACpC;AAaA,eAAsB,sBACrB,KACA,WACwB;AACxB,QAAM,aAAa,IAAI,aAAa,IAAI,SAAS,GAAG,UAAU,CAAC;AAC/D,QAAM,iBAAiB,MAAM,QAAQ;AAAA,IACpC,OAAO,OAAO,UAAU,EAEtB,OAAO,CAAC,SAAS,YAAY,KAAK,QAAQ,KAAK,WAAW,KAAK,QAAQ,CAAC,EACxE,IAAI,OAAO,SAAS;AAEpB,UAAI,YAAY,KAAK,QAAQ,GAAG;AAC/B,YAAI;AAGJ,YAAI,KAAK,IAAI;AACZ,gBAAM,eAAe,MAAM,IAAI,QAAQ;AAAA,YACtC,MAAM,IAAI,QAAQ,gBAAgB,KAAK,EAAE;AAAA,UAC1C;AACA,4BAAkB,QAAQ,KAAK,QAAQ,WAAW,OAAO,KAAK,YAAY,EAAE;AAAA,YAC3E;AAAA,UACD,CAAC;AAAA,QACF,OAAO;AACN,4BAAkB,KAAK,KAAK,SAAS,QAAQ,IAC1C,KAAK,OACL,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI;AAAA,QAC7C;AAEA,eAAO;AAAA,UACN,MAAM;AAAA,UACN,WAAW;AAAA,YACV,KAAK;AAAA,UACN;AAAA,QACD;AAAA,MACD,OAEK;AACJ,YAAI;AACJ,YAAI,KAAK,IAAI;AACZ,gBAAM,eAAe,MAAM,IAAI,QAAQ;AAAA,YACtC,MAAM,IAAI,QAAQ,gBAAgB,KAAK,EAAE;AAAA,UAC1C;AACA,wBAAc,aAAa,SAAS,OAAO;AAAA,QAC5C,OAAO;AAEN,cAAI,KAAK,KAAK,SAAS,SAAS,GAAG;AAClC,kBAAM,aAAa,KAAK,KAAK,MAAM,SAAS,EAAE,CAAC;AAC/C,0BAAc,OAAO,KAAK,YAAY,QAAQ,EAAE,SAAS,OAAO;AAAA,UACjE,OAAO;AAEN,0BAAc,OAAO,KAAK,KAAK,MAAM,QAAQ,EAAE,SAAS,OAAO;AAAA,UAChE;AAAA,QACD;AAEA,eAAO;AAAA,UACN,MAAM;AAAA,UACN,MAAM,SAAS,KAAK,YAAY,YAAY;AAAA;AAAA,EAAe,WAAW;AAAA,QACvE;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACH;AACA,SAAO,IAAI,6BAAa;AAAA,IACvB,SAAS,CAAC,GAAG,cAAc;AAAA,EAC5B,CAAC;AACF;AAgBO,SAAS,uBACf,OACmC;AACnC,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAElC,QAAM,QAAQ,CAAC,SAAS;AACvB,QAAI,gBAAgB,QAAQ,KAAK,eAAe,QAAW;AAC1D,UAAI,MAAM,QAAQ,KAAK,UAAU,GAAG;AACnC,aAAK,WAAW,QAAQ,CAAC,YAAyB;AACjD,cAAI,aAAa,WAAW,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAC3D,YAAC,QAAQ,QAA+C,QAAQ,CAAC,YAAY;AAC5E,kBAAI,QAAQ,UAAU,IAAI;AACzB,wBAAQ,QAAQ,CAAC;AAAA,cAClB;AAAA,YACD,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAiCO,SAAS,wBACf,OAC8B;AAI9B,QAAM,mBAAmB;AAEzB,MAAI,iBAAiB,cAAc;AAClC,UAAM,gBAAgB,MAAM,QAAQ,iBAAiB,cAAc,MAAM;AACzE,QAAI,eAAe;AAClB,YAAM,mBAAmB,iBAAiB,aAAa;AAQvD,YAAM,cAAc,iBAClB,OAAO,CAAC,WAAW,OAAO,SAAS,UAAU,OAAO,IAAI,EACxD,IAAI,CAAC,WAAW,OAAO,IAAI,EAC3B,KAAK,IAAI,EACT,KAAK;AAEP,UAAI,aAAa;AAChB,yBAAiB,aAAa,SAAS;AAAA,MACxC,OAAO;AACN,cAAM,kBAAkB,iBACtB,OAAO,CAAC,WAAW,OAAO,SAAS,cAAc,OAAO,QAAQ,EAChE,IAAI,CAAC,WAAW,OAAO,QAAQ,EAC/B,KAAK,IAAI,EACT,KAAK;AAEP,YAAI,iBAAiB;AACpB,2BAAiB,aAAa,SAAS;AAAA,QACxC,OAAO;AAEN,2BAAiB,aAAa,SAAS;AAAA,QACxC;AAAA,MACD;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AAUO,SAAS,uBACf,QACA,QACyD;AACzD,SAAO;AAAA,IACN,cAAc,SAAS,EAAE,QAAQ,KAAK,UAAU,MAAM,EAAE,IAAI;AAAA,IAC5D,KAAK;AAAA,EACN;AACD;AAWO,MAAM,sBACZ,CAAC,cAAgC,WACjC,OAAO,UAA6E;AAEnF,MAAI,MAAM,QAAQ,KAAK,GAAG;AACzB,UAAM,qBAAqB,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,4BAA4B;AAC1F,QAAI,sBAAsB,cAAc;AACvC,YAAM,YAAY,mBAAmB;AAErC,YAAM,cAAc,qBAAqB,SAAS,KAAK,UAAU,SAAS,IAAI;AAC9E,YAAM,eAAgB,MAAM,aAAa,MAAM,WAAW;AAC1D,aAAO,uBAAuB,cAAc,MAAM;AAAA,IACnD;AAAA,EACD;AAGA,MAAI,gBAAgB,OAAO,UAAU,YAAa,MAAsB,cAAc;AACrF,UAAM,gBAAiB,MAAsB;AAC7C,QAAI;AAEJ,QAAI,yBAAyB,QAAQ;AACpC,UAAI,YAAY,eAAe;AAC9B,YAAI;AACH,gBAAM,mBAAe,+BAAmC,cAAc,MAAM;AAI5E,cACC,iBAAiB,QACjB,OAAO,iBAAiB,YACxB,YAAY,gBACZ,OAAO,KAAK,YAAY,EAAE,WAAW,GACpC;AAED,0BAAc,KAAK,UAAU,YAAY;AAAA,UAC1C,OAAO;AAEN,0BAAc,KAAK,UAAU,EAAE,QAAQ,aAAa,CAAC;AAAA,UACtD;AAAA,QACD,SAAS,OAAO;AAEf,wBAAc,cAAc;AAAA,QAC7B;AAAA,MACD,OAAO;AAEN,sBAAc,KAAK,UAAU,aAAa;AAAA,MAC3C;AAAA,IACD,OAAO;AACN,oBAAc;AAAA,IACf;AAEA,UAAM,eAAgB,MAAM,aAAa,MAAM,WAAW;AAC1D,WAAO,uBAAuB,cAAc,MAAM;AAAA,EACnD;AAEA,SAAO,wBAAwB,KAAK;AACrC;AAYD,eAAsB,aACrB,KACA,QAAgB,GACqB;AACrC,QAAM,kBAAkB,MAAM,IAAI,uBAAuB,wCAAoB,iBAAiB,CAAC;AAE/F,MAAI;AAEJ,MAAI,MAAM,QAAQ,eAAe,KAAK,UAAU,QAAW;AAC1D,QAAI,gBAAgB,UAAU,OAAO;AACpC,aAAO;AAAA,IACR;AAEA,UAAM,iBAAiB,CAAC,GAAG,eAAe,EAAE,QAAQ;AACpD,YAAQ,eAAe,KAAK;AAAA,EAC7B,OAAO;AACN,YAAQ;AAAA,EACT;AAEA,MAAI,KAAC,+BAAe,KAAK,KAAK,CAAC,MAAM,WAAW;AAC/C,UAAM,IAAI;AAAA,MACT,IAAI,QAAQ;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAQA,eAAsB,kBACrB,KACsC;AACtC,SAAQ,MAAM,IAAI,uBAAuB,wCAAoB,UAAU,CAAC;AAGzE;AAUA,eAAsB,SACrB,KACA,cAC+C;AAC/C,QAAM,QAAS,UAAM,kCAAkB,KAAK,MAAM,KAAK;AAGvD,MAAI,cAAc;AACjB,UAAM,SAAS,sBAAsB,YAAY;AACjD,UAAM,6BAA6B,IAAI,mCAAsB;AAAA,MAC5D;AAAA,MACA,MAAM;AAAA,MACN,aACC;AAAA;AAAA,MAED,MAAM,YAAY;AAAA,IACnB,CAAC;AACD,UAAM,KAAK,0BAA0B;AAAA,EACtC;AACA,SAAO;AACR;AAUA,eAAsB,gBACrB,KACA,WACA,SAK2C;AAC3C,QAAM,mBAAmB,QAAQ,iBAAiB,IAAI,QAAQ,EAAE,cAAc;AAE9E,QAAM,WAA4C,CAAC;AAEnD,MAAI,kBAAkB;AACrB,aAAS,KAAK;AAAA,MACb;AAAA,MACA,mBAAmB,QAAQ,eAAe,kCAAkC,EAAE;AAAA,IAC/E,CAAC;AAAA,EACF,WAAW,QAAQ,cAAc;AAChC,aAAS,KAAK,CAAC,UAAU,2BAA2B,CAAC;AAAA,EACtD;AAEA,WAAS,KAAK,CAAC,eAAe,gBAAgB,GAAG,CAAC,SAAS,SAAS,CAAC;AAGrE,QAAM,gBAAgB,IAAI,aAAa,IAAI,SAAS,GAAG,WAAW;AAClE,MAAI,iBAAiB,QAAQ,yBAAyB;AACrD,UAAM,gBAAgB,MAAM,sBAAsB,KAAK,SAAS;AAChE,QAAI,cAAc,QAAQ,WAAW,GAAG;AACvC,eAAS,KAAK,aAAa;AAAA,IAC5B,OAAO;AACN,UAAI,OAAO,MAAM,2DAA2D;AAAA,IAC7E;AAAA,EACD;AAIA,WAAS,KAAK,CAAC,eAAe,oBAAoB,CAAC;AACnD,SAAO;AACR;AAQO,SAAS,cAAc,UAA+D;AAC5F,SAAO,kCAAmB,aAAa,QAAQ;AAChD;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../nodes/agents/Agent/agents/utils.ts"],"sourcesContent":["import type { BaseOutputParser } from '@langchain/core/output_parsers';\nimport type { DynamicStructuredTool, Tool } from 'langchain/tools';\nimport { NodeOperationError, type IExecuteFunctions, type INode } from 'n8n-workflow';\n\nimport type { ZodObjectAny } from '../../../../types/types';\n\nexport async function extractParsedOutput(\n\tctx: IExecuteFunctions,\n\toutputParser: BaseOutputParser<unknown>,\n\toutput: string,\n): Promise<Record<string, unknown> | undefined> {\n\tconst parsedOutput = (await outputParser.parse(output)) as {\n\t\toutput: Record<string, unknown>;\n\t};\n\n\tif (ctx.getNode().typeVersion <= 1.6) {\n\t\treturn parsedOutput;\n\t}\n\t// For 1.7 and above, we try to extract the output from the parsed output\n\t// with fallback to the original output if it's not present\n\treturn parsedOutput?.output ?? parsedOutput;\n}\n\nexport async function checkForStructuredTools(\n\ttools: Array<Tool | DynamicStructuredTool<ZodObjectAny>>,\n\tnode: INode,\n\tcurrentAgentType: string,\n) {\n\tconst dynamicStructuredTools = tools.filter(\n\t\t(tool) => tool.constructor.name === 'DynamicStructuredTool',\n\t);\n\tif (dynamicStructuredTools.length > 0) {\n\t\tconst getToolName = (tool: Tool | DynamicStructuredTool) => `\"${tool.name}\"`;\n\t\tthrow new NodeOperationError(\n\t\t\tnode,\n\t\t\t`The selected tools are not supported by \"${currentAgentType}\", please use \"Tools Agent\" instead`,\n\t\t\t{\n\t\t\t\titemIndex: 0,\n\t\t\t\tdescription: `Incompatible connected tools: ${dynamicStructuredTools.map(getToolName).join(', ')}`,\n\t\t\t},\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAuE;AAIvE,eAAsB,oBACrB,KACA,cACA,QAC+C;AAC/C,QAAM,eAAgB,MAAM,aAAa,MAAM,MAAM;AAIrD,MAAI,IAAI,QAAQ,EAAE,eAAe,KAAK;AACrC,WAAO;AAAA,EACR;AAGA,SAAO,cAAc,UAAU;AAChC;AAEA,eAAsB,wBACrB,OACA,MACA,kBACC;AACD,QAAM,yBAAyB,MAAM;AAAA,IACpC,CAAC,SAAS,KAAK,YAAY,SAAS;AAAA,EACrC;AACA,MAAI,uBAAuB,SAAS,GAAG;AACtC,UAAM,cAAc,CAAC,SAAuC,IAAI,KAAK,IAAI;AACzE,UAAM,IAAI;AAAA,MACT;AAAA,MACA,4CAA4C,gBAAgB;AAAA,MAC5D;AAAA,QACC,WAAW;AAAA,QACX,aAAa,iCAAiC,uBAAuB,IAAI,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,MACjG;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../../../nodes/agents/Agent/agents/utils.ts"],"sourcesContent":["import type { BaseOutputParser } from '@langchain/core/output_parsers';\nimport type { DynamicStructuredTool, Tool } from '@langchain/classic/tools';\nimport { NodeOperationError, type IExecuteFunctions, type INode } from 'n8n-workflow';\n\nimport type { ZodObjectAny } from '../../../../types/types';\n\nexport async function extractParsedOutput(\n\tctx: IExecuteFunctions,\n\toutputParser: BaseOutputParser<unknown>,\n\toutput: string,\n): Promise<Record<string, unknown> | undefined> {\n\tconst parsedOutput = (await outputParser.parse(output)) as {\n\t\toutput: Record<string, unknown>;\n\t};\n\n\tif (ctx.getNode().typeVersion <= 1.6) {\n\t\treturn parsedOutput;\n\t}\n\t// For 1.7 and above, we try to extract the output from the parsed output\n\t// with fallback to the original output if it's not present\n\treturn parsedOutput?.output ?? parsedOutput;\n}\n\nexport async function checkForStructuredTools(\n\ttools: Array<Tool | DynamicStructuredTool<ZodObjectAny>>,\n\tnode: INode,\n\tcurrentAgentType: string,\n) {\n\tconst dynamicStructuredTools = tools.filter(\n\t\t(tool) => tool.constructor.name === 'DynamicStructuredTool',\n\t);\n\tif (dynamicStructuredTools.length > 0) {\n\t\tconst getToolName = (tool: Tool | DynamicStructuredTool) => `\"${tool.name}\"`;\n\t\tthrow new NodeOperationError(\n\t\t\tnode,\n\t\t\t`The selected tools are not supported by \"${currentAgentType}\", please use \"Tools Agent\" instead`,\n\t\t\t{\n\t\t\t\titemIndex: 0,\n\t\t\t\tdescription: `Incompatible connected tools: ${dynamicStructuredTools.map(getToolName).join(', ')}`,\n\t\t\t},\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAAuE;AAIvE,eAAsB,oBACrB,KACA,cACA,QAC+C;AAC/C,QAAM,eAAgB,MAAM,aAAa,MAAM,MAAM;AAIrD,MAAI,IAAI,QAAQ,EAAE,eAAe,KAAK;AACrC,WAAO;AAAA,EACR;AAGA,SAAO,cAAc,UAAU;AAChC;AAEA,eAAsB,wBACrB,OACA,MACA,kBACC;AACD,QAAM,yBAAyB,MAAM;AAAA,IACpC,CAAC,SAAS,KAAK,YAAY,SAAS;AAAA,EACrC;AACA,MAAI,uBAAuB,SAAS,GAAG;AACtC,UAAM,cAAc,CAAC,SAAuC,IAAI,KAAK,IAAI;AACzE,UAAM,IAAI;AAAA,MACT;AAAA,MACA,4CAA4C,gBAAgB;AAAA,MAC5D;AAAA,QACC,WAAW;AAAA,QACX,aAAa,iCAAiC,uBAAuB,IAAI,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,MACjG;AAAA,IACD;AAAA,EACD;AACD;","names":[]}