@n8n/n8n-nodes-langchain 1.117.0 → 1.118.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credentials/McpOAuth2Api.credentials.js +45 -0
- package/dist/credentials/McpOAuth2Api.credentials.js.map +1 -0
- package/dist/known/credentials.json +10 -0
- package/dist/known/nodes.json +4 -0
- package/dist/nodes/Guardrails/Guardrails.node.js +73 -0
- package/dist/nodes/Guardrails/Guardrails.node.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/jailbreak.js +50 -0
- package/dist/nodes/Guardrails/actions/checks/jailbreak.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/keywords.js +66 -0
- package/dist/nodes/Guardrails/actions/checks/keywords.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/nsfw.js +53 -0
- package/dist/nodes/Guardrails/actions/checks/nsfw.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/pii.js +232 -0
- package/dist/nodes/Guardrails/actions/checks/pii.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/secretKeys.js +201 -0
- package/dist/nodes/Guardrails/actions/checks/secretKeys.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/topicalAlignment.js +38 -0
- package/dist/nodes/Guardrails/actions/checks/topicalAlignment.js.map +1 -0
- package/dist/nodes/Guardrails/actions/checks/urls.js +245 -0
- package/dist/nodes/Guardrails/actions/checks/urls.js.map +1 -0
- package/dist/nodes/Guardrails/actions/process.js +220 -0
- package/dist/nodes/Guardrails/actions/process.js.map +1 -0
- package/dist/nodes/Guardrails/actions/types.js +35 -0
- package/dist/nodes/Guardrails/actions/types.js.map +1 -0
- package/dist/nodes/Guardrails/description.js +454 -0
- package/dist/nodes/Guardrails/description.js.map +1 -0
- package/dist/nodes/Guardrails/guardrails.svg +11 -0
- package/dist/nodes/Guardrails/helpers/base.js +67 -0
- package/dist/nodes/Guardrails/helpers/base.js.map +1 -0
- package/dist/nodes/Guardrails/helpers/common.js +45 -0
- package/dist/nodes/Guardrails/helpers/common.js.map +1 -0
- package/dist/nodes/Guardrails/helpers/configureNodeInputs.js +50 -0
- package/dist/nodes/Guardrails/helpers/configureNodeInputs.js.map +1 -0
- package/dist/nodes/Guardrails/helpers/mappers.js +100 -0
- package/dist/nodes/Guardrails/helpers/mappers.js.map +1 -0
- package/dist/nodes/Guardrails/helpers/model.js +144 -0
- package/dist/nodes/Guardrails/helpers/model.js.map +1 -0
- package/dist/nodes/Guardrails/helpers/preflight.js +61 -0
- package/dist/nodes/Guardrails/helpers/preflight.js.map +1 -0
- package/dist/nodes/agents/Agent/V1/AgentV1.node.js +6 -0
- package/dist/nodes/agents/Agent/V1/AgentV1.node.js.map +1 -1
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js +8 -0
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -1
- package/dist/nodes/agents/Agent/V3/AgentV3.node.js +8 -0
- package/dist/nodes/agents/Agent/V3/AgentV3.node.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/SqlAgent/description.js +10 -0
- package/dist/nodes/agents/Agent/agents/SqlAgent/description.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +22 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/execute.js +8 -3
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/execute.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/config.js +4 -0
- package/dist/nodes/chains/ChainLLM/methods/config.js.map +1 -1
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js +6 -0
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js +448 -24
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/common.js +155 -0
- package/dist/nodes/llms/LMChatOpenAi/common.js.map +1 -0
- package/dist/nodes/llms/LMChatOpenAi/types.js +17 -0
- package/dist/nodes/llms/LMChatOpenAi/types.js.map +1 -0
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js +48 -3
- package/dist/nodes/mcp/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/loadOptions.js +2 -1
- package/dist/nodes/mcp/McpClientTool/loadOptions.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/types.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/utils.js +66 -4
- package/dist/nodes/mcp/McpClientTool/utils.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +45 -2
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/helpers/utils.js +5 -0
- package/dist/nodes/vendors/OpenAi/helpers/utils.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js +6 -12
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/v2/actions/text/response.operation.js +31 -6
- package/dist/nodes/vendors/OpenAi/v2/actions/text/response.operation.js.map +1 -1
- package/dist/types/credentials.json +1 -0
- package/dist/types/nodes.json +12 -11
- package/dist/utils/descriptions.js +18 -0
- package/dist/utils/descriptions.js.map +1 -1
- package/dist/utils/helpers.js +4 -1
- package/dist/utils/helpers.js.map +1 -1
- package/package.json +10 -8
|
@@ -132,6 +132,16 @@ const sqlAgentAgentProperties = [
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
},
|
|
135
|
+
{
|
|
136
|
+
...import_descriptions.textFromGuardrailsNode,
|
|
137
|
+
displayOptions: {
|
|
138
|
+
show: {
|
|
139
|
+
promptType: ["guardrails"],
|
|
140
|
+
"@version": [{ _cnd: { gte: 1.7 } }],
|
|
141
|
+
agent: ["sqlAgent"]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
135
145
|
{
|
|
136
146
|
...import_descriptions.textFromPreviousNode,
|
|
137
147
|
displayOptions: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/SqlAgent/description.ts"],"sourcesContent":["import type { INodeProperties } from 'n8n-workflow';\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../../nodes/agents/Agent/agents/SqlAgent/description.ts"],"sourcesContent":["import type { INodeProperties } from 'n8n-workflow';\n\nimport {\n\tpromptTypeOptions,\n\ttextFromGuardrailsNode,\n\ttextFromPreviousNode,\n\ttextInput,\n} from '@utils/descriptions';\n\nimport { SQL_PREFIX, SQL_SUFFIX } from './other/prompts';\n\nconst dataSourceOptions: INodeProperties = {\n\tdisplayName: 'Data Source',\n\tname: 'dataSource',\n\ttype: 'options',\n\tdisplayOptions: {\n\t\tshow: {\n\t\t\tagent: ['sqlAgent'],\n\t\t},\n\t},\n\tdefault: 'sqlite',\n\tdescription: 'SQL database to connect to',\n\toptions: [\n\t\t{\n\t\t\tname: 'MySQL',\n\t\t\tvalue: 'mysql',\n\t\t\tdescription: 'Connect to a MySQL database',\n\t\t},\n\t\t{\n\t\t\tname: 'Postgres',\n\t\t\tvalue: 'postgres',\n\t\t\tdescription: 'Connect to a Postgres database',\n\t\t},\n\t\t{\n\t\t\tname: 'SQLite',\n\t\t\tvalue: 'sqlite',\n\t\t\tdescription: 'Use SQLite by connecting a database file as binary input',\n\t\t},\n\t],\n};\n\nexport const sqlAgentAgentProperties: INodeProperties[] = [\n\t{\n\t\t...dataSourceOptions,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t\t'@version': [{ _cnd: { lt: 1.4 } }],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...dataSourceOptions,\n\t\tdefault: 'postgres',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t\t'@version': [{ _cnd: { gte: 1.4 } }],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Credentials',\n\t\tname: 'credentials',\n\t\ttype: 'credentials',\n\t\tdefault: '',\n\t},\n\t{\n\t\tdisplayName:\n\t\t\t\"Pass the SQLite database into this node as binary data, e.g. by inserting a 'Read/Write Files from Disk' node beforehand\",\n\t\tname: 'sqLiteFileNotice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t\tdataSource: ['sqlite'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Input Binary Field',\n\t\tname: 'binaryPropertyName',\n\t\ttype: 'string',\n\t\tdefault: 'data',\n\t\trequired: true,\n\t\tplaceholder: 'e.g data',\n\t\thint: 'The name of the input binary field containing the file to be extracted',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t\tdataSource: ['sqlite'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'input',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t},\n\t\t},\n\t\tdefault: '',\n\t\trequired: true,\n\t\ttypeOptions: {\n\t\t\trows: 5,\n\t\t},\n\t},\n\t{\n\t\t...promptTypeOptions,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t},\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...textFromGuardrailsNode,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tpromptType: ['guardrails'],\n\t\t\t\t'@version': [{ _cnd: { gte: 1.7 } }],\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...textFromPreviousNode,\n\t\tdisplayOptions: {\n\t\t\tshow: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.7 } }], agent: ['sqlAgent'] },\n\t\t},\n\t},\n\t{\n\t\t...textInput,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tpromptType: ['define'],\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tagent: ['sqlAgent'],\n\t\t\t},\n\t\t},\n\t\tdefault: {},\n\t\tplaceholder: 'Add Option',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Ignored Tables',\n\t\t\t\tname: 'ignoredTables',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'Comma-separated list of tables to ignore from the database. If empty, no tables are ignored.',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Include Sample Rows',\n\t\t\t\tname: 'includedSampleRows',\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription:\n\t\t\t\t\t'Number of sample rows to include in the prompt to the agent. It helps the agent to understand the schema of the database but it also increases the amount of tokens used.',\n\t\t\t\tdefault: 3,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Included Tables',\n\t\t\t\tname: 'includedTables',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription:\n\t\t\t\t\t'Comma-separated list of tables to include in the database. If empty, all tables are included.',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prefix Prompt',\n\t\t\t\tname: 'prefixPrompt',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: SQL_PREFIX,\n\t\t\t\tdescription: 'Prefix prompt to use for the agent',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 10,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Suffix Prompt',\n\t\t\t\tname: 'suffixPrompt',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: SQL_SUFFIX,\n\t\t\t\tdescription: 'Suffix prompt to use for the agent',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 4,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Limit',\n\t\t\t\tname: 'topK',\n\t\t\t\ttype: 'number',\n\t\t\t\tdefault: 10,\n\t\t\t\tdescription: 'The maximum number of results to return',\n\t\t\t},\n\t\t],\n\t},\n];\n"],"mappings":"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","names":[]}
|
|
@@ -40,6 +40,7 @@ var import_helpers = require("../../../../../../utils/helpers");
|
|
|
40
40
|
var import_N8nOutputParser = require("../../../../../../utils/output_parsers/N8nOutputParser");
|
|
41
41
|
var import_common = require("../common");
|
|
42
42
|
var import_prompt = require("../prompt");
|
|
43
|
+
var import_openai = require("@langchain/openai");
|
|
43
44
|
function createAgentExecutor(model, tools, prompt, options, outputParser, memory, fallbackModel) {
|
|
44
45
|
const agent = (0, import_agents.createToolCallingAgent)({
|
|
45
46
|
llm: model,
|
|
@@ -138,7 +139,16 @@ async function processEventStream(ctx, eventStream, itemIndex, returnIntermediat
|
|
|
138
139
|
ctx.sendChunk("end", itemIndex);
|
|
139
140
|
return agentResult;
|
|
140
141
|
}
|
|
142
|
+
function checkIsResponsesApi(model) {
|
|
143
|
+
try {
|
|
144
|
+
const isUsingResponsesApi = !!model && model instanceof import_openai.ChatOpenAI && "useResponsesApi" in model && model.useResponsesApi;
|
|
145
|
+
return isUsingResponsesApi;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
141
150
|
async function toolsAgentExecute() {
|
|
151
|
+
const version = this.getNode().typeVersion;
|
|
142
152
|
this.logger.debug("Executing Tools Agent V2");
|
|
143
153
|
const returnData = [];
|
|
144
154
|
const items = this.getInputData();
|
|
@@ -153,6 +163,18 @@ async function toolsAgentExecute() {
|
|
|
153
163
|
const model = await (0, import_common.getChatModel)(this, 0);
|
|
154
164
|
(0, import_node_assert.default)(model, "Please connect a model to the Chat Model input");
|
|
155
165
|
const fallbackModel = needsFallback ? await (0, import_common.getChatModel)(this, 1) : null;
|
|
166
|
+
if (checkIsResponsesApi(model)) {
|
|
167
|
+
throw new import_n8n_workflow.NodeOperationError(
|
|
168
|
+
this.getNode(),
|
|
169
|
+
`This model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (checkIsResponsesApi(fallbackModel)) {
|
|
173
|
+
throw new import_n8n_workflow.NodeOperationError(
|
|
174
|
+
this.getNode(),
|
|
175
|
+
`This fallback model is not supported in ${version} version of the Agent node. Please upgrade the Agent node to the latest version.`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
156
178
|
if (needsFallback && !fallbackModel) {
|
|
157
179
|
throw new import_n8n_workflow.NodeOperationError(
|
|
158
180
|
this.getNode(),
|
|
@@ -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';\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\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\tthis.logger.debug('Executing Tools Agent V2');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\t// Check if streaming is enabled\n\tconst enableStreaming = this.getNodeParameter('options.enableStreaming', 0, true) as boolean;\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tconst input = getPromptInputByType({\n\t\t\t\tctx: this,\n\t\t\t\ti: itemIndex,\n\t\t\t\tinputKey: 'text',\n\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t});\n\t\t\tif (input === undefined) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The \"text\" parameter is empty.');\n\t\t\t}\n\t\t\tconst outputParser = await getOptionalOutputParser(this, itemIndex);\n\t\t\tconst tools = await getTools(this, outputParser);\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemMessage?: string;\n\t\t\t\tmaxIterations?: number;\n\t\t\t\treturnIntermediateSteps?: boolean;\n\t\t\t\tpassthroughBinaryImages?: boolean;\n\t\t\t};\n\n\t\t\t// Prepare the prompt messages and prompt template.\n\t\t\tconst messages = await prepareMessages(this, itemIndex, {\n\t\t\t\tsystemMessage: options.systemMessage,\n\t\t\t\tpassthroughBinaryImages: options.passthroughBinaryImages ?? true,\n\t\t\t\toutputParser,\n\t\t\t});\n\t\t\tconst prompt: ChatPromptTemplate = preparePrompt(messages);\n\n\t\t\t// Create executors for primary and fallback models\n\t\t\tconst executor = createAgentExecutor(\n\t\t\t\tmodel,\n\t\t\t\ttools,\n\t\t\t\tprompt,\n\t\t\t\toptions,\n\t\t\t\toutputParser,\n\t\t\t\tmemory,\n\t\t\t\tfallbackModel,\n\t\t\t);\n\t\t\t// Invoke with fallback logic\n\t\t\tconst invokeParams = {\n\t\t\t\tinput,\n\t\t\t\tsystem_message: options.systemMessage ?? SYSTEM_MESSAGE,\n\t\t\t\tformatting_instructions:\n\t\t\t\t\t'IMPORTANT: For your response to user, you MUST use the `format_final_json_response` tool with your complete answer formatted according to the required schema. Do not attempt to format the JSON manually - always use this tool. Your response will be rejected if it is not properly formatted through this tool. Only use this tool once you are ready to provide your final answer.',\n\t\t\t};\n\t\t\tconst executeOptions = { signal: this.getExecutionCancelSignal() };\n\n\t\t\t// Check if streaming is actually available\n\t\t\tconst isStreamingAvailable = '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;AAK/B,SAAS,oBACR,OACA,OACA,QACA,SACA,cACA,QACA,eACC;AACD,QAAM,YAAQ,sCAAuB;AAAA,IACpC,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EACjB,CAAC;AAED,MAAI;AACJ,MAAI,eAAe;AAClB,wBAAgB,sCAAuB;AAAA,MACtC,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IACjB,CAAC;AAAA,EACF;AACA,QAAM,gBAAgB,kCAAiB,KAAK;AAAA,IAC3C,gBAAgB,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI;AAAA,QACvD,mCAAoB,cAAc,MAAM;AAAA,IACxC;AAAA,EACD,CAAC;AAED,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;AAgBA,eAAsB,oBAEa;AAClC,OAAK,OAAO,MAAM,0BAA0B;AAE5C,QAAM,aAAmC,CAAC;AAC1C,QAAM,QAAQ,KAAK,aAAa;AAChC,QAAM,YAAY,KAAK,iBAAiB,8BAA8B,GAAG,CAAC;AAC1E,QAAM,sBAAsB,KAAK;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,gBAAgB,KAAK,iBAAiB,iBAAiB,GAAG,KAAK;AACrE,QAAM,SAAS,UAAM,iCAAkB,IAAI;AAC3C,QAAM,QAAQ,UAAM,4BAAa,MAAM,CAAC;AACxC,yBAAAA,SAAO,OAAO,gDAAgD;AAC9D,QAAM,gBAAgB,gBAAgB,UAAM,4BAAa,MAAM,CAAC,IAAI;AAEpE,MAAI,iBAAiB,CAAC,eAAe;AACpC,UAAM,IAAI;AAAA,MACT,KAAK,QAAQ;AAAA,MACb;AAAA,IACD;AAAA,EACD;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
|
+
{"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"]}
|
|
@@ -58,10 +58,15 @@ async function createEngineRequests(toolCalls, itemIndex, tools) {
|
|
|
58
58
|
};
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
+
function getAllTools(model, tools) {
|
|
62
|
+
const modelTools = model.metadata?.tools ?? [];
|
|
63
|
+
const allTools = [...tools, ...modelTools];
|
|
64
|
+
return allTools;
|
|
65
|
+
}
|
|
61
66
|
function createAgentSequence(model, tools, prompt, _options, outputParser, memory, fallbackModel) {
|
|
62
67
|
const agent = (0, import_agents.createToolCallingAgent)({
|
|
63
68
|
llm: model,
|
|
64
|
-
tools,
|
|
69
|
+
tools: getAllTools(model, tools),
|
|
65
70
|
prompt,
|
|
66
71
|
streamRunnable: false
|
|
67
72
|
});
|
|
@@ -69,7 +74,7 @@ function createAgentSequence(model, tools, prompt, _options, outputParser, memor
|
|
|
69
74
|
if (fallbackModel) {
|
|
70
75
|
fallbackAgent = (0, import_agents.createToolCallingAgent)({
|
|
71
76
|
llm: fallbackModel,
|
|
72
|
-
tools,
|
|
77
|
+
tools: getAllTools(fallbackModel, tools),
|
|
73
78
|
prompt,
|
|
74
79
|
streamRunnable: false
|
|
75
80
|
});
|
|
@@ -209,7 +214,7 @@ function buildSteps(response, itemIndex) {
|
|
|
209
214
|
toolCallId: toolInput?.id,
|
|
210
215
|
type: toolInput.type || "tool_call"
|
|
211
216
|
},
|
|
212
|
-
observation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.
|
|
217
|
+
observation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.map((item) => item?.json) ?? "")
|
|
213
218
|
};
|
|
214
219
|
steps.push(toolResult);
|
|
215
220
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/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, BaseMessage, MessageContentText } from '@langchain/core/messages';\nimport { AIMessage, trimMessages } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\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';\nimport omit from 'lodash/omit';\nimport {\n\tjsonParse,\n\tNodeConnectionTypes,\n\tnodeNameToToolName,\n\tNodeOperationError,\n\tsleep,\n} from 'n8n-workflow';\nimport type {\n\tEngineRequest,\n\tGenericValue,\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tISupplyDataFunctions,\n\tEngineResponse,\n} from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\ntype ToolCallRequest = {\n\ttool: string;\n\ttoolInput: Record<string, unknown>;\n\ttoolCallId: string;\n\ttype?: string;\n\tlog?: string;\n\tmessageLog?: unknown[];\n};\n\nasync function createEngineRequests(\n\ttoolCalls: ToolCallRequest[],\n\titemIndex: number,\n\ttools: Array<DynamicStructuredTool | Tool>,\n) {\n\treturn toolCalls.map((toolCall) => {\n\t\t// First try to get from metadata (for toolkit tools)\n\t\tconst foundTool = tools.find((tool) => tool.name === toolCall.tool);\n\n\t\tif (!foundTool) return;\n\n\t\tconst nodeName = foundTool.metadata?.sourceNodeName;\n\n\t\t// For toolkit tools, include the tool name so the node knows which tool to execute\n\t\tconst input = foundTool.metadata?.isFromToolkit\n\t\t\t? { ...toolCall.toolInput, tool: toolCall.tool }\n\t\t\t: toolCall.toolInput;\n\n\t\treturn {\n\t\t\tnodeName,\n\t\t\tinput,\n\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\tid: toolCall.toolCallId,\n\t\t\tmetadata: {\n\t\t\t\titemIndex,\n\t\t\t},\n\t\t};\n\t});\n}\n\n/**\n * Creates an agent executor with the given configuration\n */\nfunction 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,\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 = true;\n\trunnableAgent.streamRunnable = false;\n\n\treturn runnableAgent;\n}\n\ntype IntermediateStep = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string;\n\t\tmessageLog: unknown[];\n\t\ttoolCallId: string;\n\t\ttype: string;\n\t};\n\tobservation?: string;\n};\n\ntype AgentResult = {\n\toutput: string;\n\tintermediateSteps?: IntermediateStep[];\n\ttoolCalls?: ToolCallRequest[];\n};\n\nasync function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n\treturnIntermediateSteps: boolean = false,\n\tmemory?: BaseChatMemory,\n\tinput?: string,\n): Promise<AgentResult> {\n\tconst agentResult: AgentResult = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tconst toolCalls: ToolCallRequest[] = [];\n\n\tctx.sendChunk('begin', itemIndex);\n\tfor await (const event of eventStream) {\n\t\t// Stream chat model tokens as they come in\n\t\tswitch (event.event) {\n\t\t\tcase 'on_chat_model_stream':\n\t\t\t\tconst chunk = event.data?.chunk as AIMessageChunk;\n\t\t\t\tif (chunk?.content) {\n\t\t\t\t\tconst chunkContent = chunk.content;\n\t\t\t\t\tlet chunkText = '';\n\t\t\t\t\tif (Array.isArray(chunkContent)) {\n\t\t\t\t\t\tfor (const message of chunkContent) {\n\t\t\t\t\t\t\tif (message?.type === 'text') {\n\t\t\t\t\t\t\t\tchunkText += (message as MessageContentText)?.text;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (typeof chunkContent === 'string') {\n\t\t\t\t\t\tchunkText = chunkContent;\n\t\t\t\t\t}\n\t\t\t\t\tctx.sendChunk('item', itemIndex, chunkText);\n\n\t\t\t\t\tagentResult.output += chunkText;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_chat_model_end':\n\t\t\t\t// Capture full LLM response with tool calls for intermediate steps\n\t\t\t\tif (event.data) {\n\t\t\t\t\tconst chatModelData = event.data as {\n\t\t\t\t\t\toutput?: { tool_calls?: ToolCall[]; content?: string };\n\t\t\t\t\t};\n\t\t\t\t\tconst output = chatModelData.output;\n\n\t\t\t\t\t// Check if this LLM response contains tool calls\n\t\t\t\t\tif (output?.tool_calls && output.tool_calls.length > 0) {\n\t\t\t\t\t\t// Collect tool calls for request building\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\tmessageLog: [output],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Also add to intermediate steps if needed\n\t\t\t\t\t\tif (returnIntermediateSteps) {\n\t\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\t\tagentResult.intermediateSteps!.push({\n\t\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\t\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_tool_end':\n\t\t\t\t// Capture tool execution results and match with action\n\t\t\t\tif (returnIntermediateSteps && event.data && agentResult.intermediateSteps!.length > 0) {\n\t\t\t\t\tconst toolData = event.data as { output?: string };\n\t\t\t\t\t// Find the matching intermediate step for this tool call\n\t\t\t\t\tconst matchingStep = agentResult.intermediateSteps!.find(\n\t\t\t\t\t\t(step) => !step.observation && step.action.tool === event.name,\n\t\t\t\t\t);\n\t\t\t\t\tif (matchingStep) {\n\t\t\t\t\t\tmatchingStep.observation = toolData.output || '';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\t// Save conversation to memory if memory is connected\n\tif (memory && input && agentResult.output) {\n\t\tawait memory.saveContext({ input }, { output: agentResult.output });\n\t}\n\n\t// Include collected tool calls in the result\n\tif (toolCalls.length > 0) {\n\t\tagentResult.toolCalls = toolCalls;\n\t}\n\n\treturn agentResult;\n}\n\nexport type RequestResponseMetadata = {\n\titemIndex?: number;\n\tpreviousRequests: ToolCallData[];\n\titerationCount?: number;\n};\n\ntype ToolCallData = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string | number | true | object;\n\t\ttoolCallId: IDataObject | GenericValue | GenericValue[] | IDataObject[];\n\t\ttype: string | number | true | object;\n\t};\n\tobservation: string;\n};\n\nfunction buildSteps(\n\tresponse: EngineResponse<RequestResponseMetadata> | undefined,\n\titemIndex: number,\n): ToolCallData[] {\n\tconst steps: ToolCallData[] = [];\n\n\tif (response) {\n\t\tconst responses = response?.actionResponses ?? [];\n\n\t\tif (response.metadata?.previousRequests) {\n\t\t\tsteps.push(...response.metadata.previousRequests);\n\t\t}\n\n\t\tfor (const tool of responses) {\n\t\t\tif (tool.action?.metadata?.itemIndex !== itemIndex) continue;\n\n\t\t\tconst toolInput: IDataObject = {\n\t\t\t\t...tool.action.input,\n\t\t\t\tid: tool.action.id,\n\t\t\t};\n\t\t\tif (!toolInput || !tool.data) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst step = steps.find((step) => step.action.toolCallId === toolInput.id);\n\t\t\tif (step) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Create a synthetic AI message for the messageLog\n\t\t\t// This represents the AI's decision to call the tool\n\t\t\tconst syntheticAIMessage = new AIMessage({\n\t\t\t\tcontent: `Calling ${tool.action.nodeName} with input: ${JSON.stringify(toolInput)}`,\n\t\t\t\ttool_calls: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: (toolInput?.id as string) ?? 'reconstructed_call',\n\t\t\t\t\t\tname: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\t\targs: toolInput,\n\t\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\n\t\t\tconst toolResult = {\n\t\t\t\taction: {\n\t\t\t\t\ttool: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\ttoolInput: (toolInput.input as IDataObject) || {},\n\t\t\t\t\tlog: toolInput.log || syntheticAIMessage.content,\n\t\t\t\t\tmessageLog: [syntheticAIMessage],\n\t\t\t\t\ttoolCallId: toolInput?.id,\n\t\t\t\t\ttype: toolInput.type || 'tool_call',\n\t\t\t\t},\n\t\t\t\tobservation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.[0]?.json ?? ''),\n\t\t\t};\n\n\t\t\tsteps.push(toolResult);\n\t\t}\n\t}\n\treturn steps;\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\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<INodeExecutionData[][] | EngineRequest<RequestResponseMetadata>> {\n\tthis.logger.debug('Executing Tools Agent V3');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tlet request: EngineRequest<RequestResponseMetadata> | undefined = undefined;\n\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tif (response && response?.metadata?.itemIndex === itemIndex) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst steps = buildSteps(response, itemIndex);\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\tenableStreaming?: boolean;\n\t\t\t\tmaxTokensFromMemory?: number;\n\t\t\t};\n\n\t\t\tif (options.enableStreaming === undefined) {\n\t\t\t\toptions.enableStreaming = true;\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 = createAgentSequence(\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\tsteps,\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\toptions.enableStreaming &&\n\t\t\t\tisStreamingAvailable &&\n\t\t\t\tthis.getNode().typeVersion >= 2.1\n\t\t\t) {\n\t\t\t\tlet chatHistory: BaseMessage[] | undefined = undefined;\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\tchatHistory = await loadChatHistory(memory, model, options.maxTokensFromMemory);\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,\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\tconst result = 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\tmemory,\n\t\t\t\t\tinput,\n\t\t\t\t);\n\n\t\t\t\t// If result contains tool calls, build the request object like the normal flow\n\t\t\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\t\t\tconst currentIteration = (response?.metadata?.iterationCount ?? 0) + 1;\n\n\t\t\t\t\t// Check if we've exceeded maxIterations\n\t\t\t\t\tif (options.maxIterations && currentIteration > options.maxIterations) {\n\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'Maximum iterations reached');\n\t\t\t\t\t}\n\n\t\t\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tactions,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tpreviousRequests: buildSteps(response, itemIndex),\n\t\t\t\t\t\t\titerationCount: currentIteration,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} else {\n\t\t\t\t// Handle regular execution\n\t\t\t\tlet chatHistory: BaseMessage[] | undefined = undefined;\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\tchatHistory = await loadChatHistory(memory, model, options.maxTokensFromMemory);\n\t\t\t\t}\n\t\t\t\tconst modelResponse = await executor.invoke({\n\t\t\t\t\t...invokeParams,\n\t\t\t\t\tchat_history: chatHistory,\n\t\t\t\t});\n\n\t\t\t\tif ('returnValues' in modelResponse) {\n\t\t\t\t\t// Save conversation to memory including any tool call context\n\t\t\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\t\t\t// If there were tool calls in this conversation, include them in the context\n\t\t\t\t\t\tlet fullOutput = modelResponse.returnValues.output as string;\n\n\t\t\t\t\t\tif (steps.length > 0) {\n\t\t\t\t\t\t\t// Include tool call information in the conversation context\n\t\t\t\t\t\t\tconst toolContext = steps\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t(step) =>\n\t\t\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\t\t)\n\t\t\t\t\t\t\t\t.join('; ');\n\t\t\t\t\t\t\tfullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait memory.saveContext({ input }, { output: fullOutput });\n\t\t\t\t\t}\n\t\t\t\t\t// Include intermediate steps if requested\n\t\t\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tconst currentIteration = (response?.metadata?.iterationCount ?? 0) + 1;\n\n\t\t\t\t// Check if we've exceeded maxIterations\n\t\t\t\tif (options.maxIterations && currentIteration > options.maxIterations) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'Maximum iterations reached');\n\t\t\t\t}\n\n\t\t\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\t\t\treturn {\n\t\t\t\t\tactions,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tpreviousRequests: buildSteps(response, itemIndex),\n\t\t\t\t\t\titerationCount: currentIteration,\n\t\t\t\t\t},\n\t\t\t\t};\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} as INodeExecutionData);\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\n\t\t\tif ('actions' in response) {\n\t\t\t\tif (!request) {\n\t\t\t\t\trequest = {\n\t\t\t\t\t\tactions: response.actions,\n\t\t\t\t\t\tmetadata: response.metadata,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\trequest.actions.push(...response.actions);\n\t\t\t\t}\n\t\t\t\treturn;\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: INodeExecutionData = {\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\t// Check if we have any Request objects (tool calls)\n\tif (request) {\n\t\treturn request;\n\t}\n\n\t// Otherwise return execution data\n\treturn [returnData];\n}\nasync function loadChatHistory(\n\tmemory: BaseChatMemory,\n\tmodel: BaseChatModel,\n\tmaxTokensFromMemory?: number,\n): Promise<BaseMessage[]> {\n\tconst memoryVariables = await memory.loadMemoryVariables({});\n\tlet chatHistory = memoryVariables['chat_history'] as BaseMessage[];\n\n\tif (maxTokensFromMemory) {\n\t\tchatHistory = await trimMessages(chatHistory, {\n\t\t\tstrategy: 'last',\n\t\t\tmaxTokens: maxTokensFromMemory,\n\t\t\ttokenCounter: model,\n\t\t\tincludeSystem: true,\n\t\t\tstartOn: 'human',\n\t\t\tallowPartial: true,\n\t\t});\n\t}\n\n\treturn chatHistory;\n}\n"],"mappings":"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","names":["step","assert","outputParser","response","omit"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../nodes/agents/Agent/agents/ToolsAgent/V3/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, BaseMessage, MessageContentText } from '@langchain/core/messages';\nimport { AIMessage, trimMessages } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\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';\nimport omit from 'lodash/omit';\nimport {\n\tjsonParse,\n\tNodeConnectionTypes,\n\tnodeNameToToolName,\n\tNodeOperationError,\n\tsleep,\n} from 'n8n-workflow';\nimport type {\n\tEngineRequest,\n\tGenericValue,\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tISupplyDataFunctions,\n\tEngineResponse,\n} from 'n8n-workflow';\nimport assert from 'node:assert';\n\nimport { getPromptInputByType } from '@utils/helpers';\nimport {\n\tgetOptionalOutputParser,\n\ttype N8nOutputParser,\n} from '@utils/output_parsers/N8nOutputParser';\n\nimport {\n\tfixEmptyContentMessage,\n\tgetAgentStepsParser,\n\tgetChatModel,\n\tgetOptionalMemory,\n\tgetTools,\n\tprepareMessages,\n\tpreparePrompt,\n} from '../common';\nimport { SYSTEM_MESSAGE } from '../prompt';\n\ntype ToolCallRequest = {\n\ttool: string;\n\ttoolInput: Record<string, unknown>;\n\ttoolCallId: string;\n\ttype?: string;\n\tlog?: string;\n\tmessageLog?: unknown[];\n};\n\nasync function createEngineRequests(\n\ttoolCalls: ToolCallRequest[],\n\titemIndex: number,\n\ttools: Array<DynamicStructuredTool | Tool>,\n) {\n\treturn toolCalls.map((toolCall) => {\n\t\t// First try to get from metadata (for toolkit tools)\n\t\tconst foundTool = tools.find((tool) => tool.name === toolCall.tool);\n\n\t\tif (!foundTool) return;\n\n\t\tconst nodeName = foundTool.metadata?.sourceNodeName;\n\n\t\t// For toolkit tools, include the tool name so the node knows which tool to execute\n\t\tconst input = foundTool.metadata?.isFromToolkit\n\t\t\t? { ...toolCall.toolInput, tool: toolCall.tool }\n\t\t\t: toolCall.toolInput;\n\n\t\treturn {\n\t\t\tnodeName,\n\t\t\tinput,\n\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\tid: toolCall.toolCallId,\n\t\t\tmetadata: {\n\t\t\t\titemIndex,\n\t\t\t},\n\t\t};\n\t});\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\n/**\n * Creates an agent executor with the given configuration\n */\nfunction 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\ntype IntermediateStep = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string;\n\t\tmessageLog: unknown[];\n\t\ttoolCallId: string;\n\t\ttype: string;\n\t};\n\tobservation?: string;\n};\n\ntype AgentResult = {\n\toutput: string;\n\tintermediateSteps?: IntermediateStep[];\n\ttoolCalls?: ToolCallRequest[];\n};\n\nasync function processEventStream(\n\tctx: IExecuteFunctions,\n\teventStream: IterableReadableStream<StreamEvent>,\n\titemIndex: number,\n\treturnIntermediateSteps: boolean = false,\n\tmemory?: BaseChatMemory,\n\tinput?: string,\n): Promise<AgentResult> {\n\tconst agentResult: AgentResult = {\n\t\toutput: '',\n\t};\n\n\tif (returnIntermediateSteps) {\n\t\tagentResult.intermediateSteps = [];\n\t}\n\n\tconst toolCalls: ToolCallRequest[] = [];\n\n\tctx.sendChunk('begin', itemIndex);\n\tfor await (const event of eventStream) {\n\t\t// Stream chat model tokens as they come in\n\t\tswitch (event.event) {\n\t\t\tcase 'on_chat_model_stream':\n\t\t\t\tconst chunk = event.data?.chunk as AIMessageChunk;\n\t\t\t\tif (chunk?.content) {\n\t\t\t\t\tconst chunkContent = chunk.content;\n\t\t\t\t\tlet chunkText = '';\n\t\t\t\t\tif (Array.isArray(chunkContent)) {\n\t\t\t\t\t\tfor (const message of chunkContent) {\n\t\t\t\t\t\t\tif (message?.type === 'text') {\n\t\t\t\t\t\t\t\tchunkText += (message as MessageContentText)?.text;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (typeof chunkContent === 'string') {\n\t\t\t\t\t\tchunkText = chunkContent;\n\t\t\t\t\t}\n\t\t\t\t\tctx.sendChunk('item', itemIndex, chunkText);\n\n\t\t\t\t\tagentResult.output += chunkText;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_chat_model_end':\n\t\t\t\t// Capture full LLM response with tool calls for intermediate steps\n\t\t\t\tif (event.data) {\n\t\t\t\t\tconst chatModelData = event.data as {\n\t\t\t\t\t\toutput?: { tool_calls?: ToolCall[]; content?: string };\n\t\t\t\t\t};\n\t\t\t\t\tconst output = chatModelData.output;\n\n\t\t\t\t\t// Check if this LLM response contains tool calls\n\t\t\t\t\tif (output?.tool_calls && output.tool_calls.length > 0) {\n\t\t\t\t\t\t// Collect tool calls for request building\n\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\tmessageLog: [output],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Also add to intermediate steps if needed\n\t\t\t\t\t\tif (returnIntermediateSteps) {\n\t\t\t\t\t\t\tfor (const toolCall of output.tool_calls) {\n\t\t\t\t\t\t\t\tagentResult.intermediateSteps!.push({\n\t\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\t\ttool: toolCall.name,\n\t\t\t\t\t\t\t\t\t\ttoolInput: toolCall.args,\n\t\t\t\t\t\t\t\t\t\tlog:\n\t\t\t\t\t\t\t\t\t\t\toutput.content ||\n\t\t\t\t\t\t\t\t\t\t\t`Calling ${toolCall.name} with input: ${JSON.stringify(toolCall.args)}`,\n\t\t\t\t\t\t\t\t\t\tmessageLog: [output], // Include the full LLM response\n\t\t\t\t\t\t\t\t\t\ttoolCallId: toolCall.id || 'unknown',\n\t\t\t\t\t\t\t\t\t\ttype: toolCall.type || 'tool_call',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'on_tool_end':\n\t\t\t\t// Capture tool execution results and match with action\n\t\t\t\tif (returnIntermediateSteps && event.data && agentResult.intermediateSteps!.length > 0) {\n\t\t\t\t\tconst toolData = event.data as { output?: string };\n\t\t\t\t\t// Find the matching intermediate step for this tool call\n\t\t\t\t\tconst matchingStep = agentResult.intermediateSteps!.find(\n\t\t\t\t\t\t(step) => !step.observation && step.action.tool === event.name,\n\t\t\t\t\t);\n\t\t\t\t\tif (matchingStep) {\n\t\t\t\t\t\tmatchingStep.observation = toolData.output || '';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tctx.sendChunk('end', itemIndex);\n\n\t// Save conversation to memory if memory is connected\n\tif (memory && input && agentResult.output) {\n\t\tawait memory.saveContext({ input }, { output: agentResult.output });\n\t}\n\n\t// Include collected tool calls in the result\n\tif (toolCalls.length > 0) {\n\t\tagentResult.toolCalls = toolCalls;\n\t}\n\n\treturn agentResult;\n}\n\nexport type RequestResponseMetadata = {\n\titemIndex?: number;\n\tpreviousRequests: ToolCallData[];\n\titerationCount?: number;\n};\n\ntype ToolCallData = {\n\taction: {\n\t\ttool: string;\n\t\ttoolInput: Record<string, unknown>;\n\t\tlog: string | number | true | object;\n\t\ttoolCallId: IDataObject | GenericValue | GenericValue[] | IDataObject[];\n\t\ttype: string | number | true | object;\n\t};\n\tobservation: string;\n};\n\nfunction buildSteps(\n\tresponse: EngineResponse<RequestResponseMetadata> | undefined,\n\titemIndex: number,\n): ToolCallData[] {\n\tconst steps: ToolCallData[] = [];\n\n\tif (response) {\n\t\tconst responses = response?.actionResponses ?? [];\n\n\t\tif (response.metadata?.previousRequests) {\n\t\t\tsteps.push(...response.metadata.previousRequests);\n\t\t}\n\n\t\tfor (const tool of responses) {\n\t\t\tif (tool.action?.metadata?.itemIndex !== itemIndex) continue;\n\n\t\t\tconst toolInput: IDataObject = {\n\t\t\t\t...tool.action.input,\n\t\t\t\tid: tool.action.id,\n\t\t\t};\n\t\t\tif (!toolInput || !tool.data) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst step = steps.find((step) => step.action.toolCallId === toolInput.id);\n\t\t\tif (step) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Create a synthetic AI message for the messageLog\n\t\t\t// This represents the AI's decision to call the tool\n\t\t\tconst syntheticAIMessage = new AIMessage({\n\t\t\t\tcontent: `Calling ${tool.action.nodeName} with input: ${JSON.stringify(toolInput)}`,\n\t\t\t\ttool_calls: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: (toolInput?.id as string) ?? 'reconstructed_call',\n\t\t\t\t\t\tname: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\t\targs: toolInput,\n\t\t\t\t\t\ttype: 'tool_call',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\n\t\t\tconst toolResult = {\n\t\t\t\taction: {\n\t\t\t\t\ttool: nodeNameToToolName(tool.action.nodeName),\n\t\t\t\t\ttoolInput: (toolInput.input as IDataObject) || {},\n\t\t\t\t\tlog: toolInput.log || syntheticAIMessage.content,\n\t\t\t\t\tmessageLog: [syntheticAIMessage],\n\t\t\t\t\ttoolCallId: toolInput?.id,\n\t\t\t\t\ttype: toolInput.type || 'tool_call',\n\t\t\t\t},\n\t\t\t\tobservation: JSON.stringify(tool.data?.data?.ai_tool?.[0]?.map((item) => item?.json) ?? ''),\n\t\t\t};\n\n\t\t\tsteps.push(toolResult);\n\t\t}\n\t}\n\treturn steps;\n}\n\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\tresponse?: EngineResponse<RequestResponseMetadata>,\n): Promise<INodeExecutionData[][] | EngineRequest<RequestResponseMetadata>> {\n\tthis.logger.debug('Executing Tools Agent V3');\n\n\tconst returnData: INodeExecutionData[] = [];\n\tlet request: EngineRequest<RequestResponseMetadata> | undefined = undefined;\n\n\tconst items = this.getInputData();\n\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 1) as number;\n\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t'options.batching.delayBetweenBatches',\n\t\t0,\n\t\t0,\n\t) as number;\n\tconst needsFallback = this.getNodeParameter('needsFallback', 0, false) as boolean;\n\tconst memory = await getOptionalMemory(this);\n\tconst model = await getChatModel(this, 0);\n\tassert(model, 'Please connect a model to the Chat Model input');\n\tconst fallbackModel = needsFallback ? await getChatModel(this, 1) : null;\n\n\tif (needsFallback && !fallbackModel) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t'Please connect a model to the Fallback Model input or disable the fallback option',\n\t\t);\n\t}\n\n\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\tconst batch = items.slice(i, i + batchSize);\n\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\tif (response && response?.metadata?.itemIndex === itemIndex) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst steps = buildSteps(response, itemIndex);\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\tenableStreaming?: boolean;\n\t\t\t\tmaxTokensFromMemory?: number;\n\t\t\t};\n\n\t\t\tif (options.enableStreaming === undefined) {\n\t\t\t\toptions.enableStreaming = true;\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 = createAgentSequence(\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\tsteps,\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\toptions.enableStreaming &&\n\t\t\t\tisStreamingAvailable &&\n\t\t\t\tthis.getNode().typeVersion >= 2.1\n\t\t\t) {\n\t\t\t\tlet chatHistory: BaseMessage[] | undefined = undefined;\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\tchatHistory = await loadChatHistory(memory, model, options.maxTokensFromMemory);\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,\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\tconst result = 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\tmemory,\n\t\t\t\t\tinput,\n\t\t\t\t);\n\n\t\t\t\t// If result contains tool calls, build the request object like the normal flow\n\t\t\t\tif (result.toolCalls && result.toolCalls.length > 0) {\n\t\t\t\t\tconst currentIteration = (response?.metadata?.iterationCount ?? 0) + 1;\n\n\t\t\t\t\t// Check if we've exceeded maxIterations\n\t\t\t\t\tif (options.maxIterations && currentIteration > options.maxIterations) {\n\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'Maximum iterations reached');\n\t\t\t\t\t}\n\n\t\t\t\t\tconst actions = await createEngineRequests(result.toolCalls, itemIndex, tools);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tactions,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tpreviousRequests: buildSteps(response, itemIndex),\n\t\t\t\t\t\t\titerationCount: currentIteration,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} else {\n\t\t\t\t// Handle regular execution\n\t\t\t\tlet chatHistory: BaseMessage[] | undefined = undefined;\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\tchatHistory = await loadChatHistory(memory, model, options.maxTokensFromMemory);\n\t\t\t\t}\n\t\t\t\tconst modelResponse = await executor.invoke({\n\t\t\t\t\t...invokeParams,\n\t\t\t\t\tchat_history: chatHistory,\n\t\t\t\t});\n\n\t\t\t\tif ('returnValues' in modelResponse) {\n\t\t\t\t\t// Save conversation to memory including any tool call context\n\t\t\t\t\tif (memory && input && modelResponse.returnValues.output) {\n\t\t\t\t\t\t// If there were tool calls in this conversation, include them in the context\n\t\t\t\t\t\tlet fullOutput = modelResponse.returnValues.output as string;\n\n\t\t\t\t\t\tif (steps.length > 0) {\n\t\t\t\t\t\t\t// Include tool call information in the conversation context\n\t\t\t\t\t\t\tconst toolContext = steps\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t(step) =>\n\t\t\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\t\t)\n\t\t\t\t\t\t\t\t.join('; ');\n\t\t\t\t\t\t\tfullOutput = `[Used tools: ${toolContext}] ${fullOutput}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait memory.saveContext({ input }, { output: fullOutput });\n\t\t\t\t\t}\n\t\t\t\t\t// Include intermediate steps if requested\n\t\t\t\t\tconst result = { ...modelResponse.returnValues };\n\t\t\t\t\tif (options.returnIntermediateSteps && steps.length > 0) {\n\t\t\t\t\t\tresult.intermediateSteps = steps;\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tconst currentIteration = (response?.metadata?.iterationCount ?? 0) + 1;\n\n\t\t\t\t// Check if we've exceeded maxIterations\n\t\t\t\tif (options.maxIterations && currentIteration > options.maxIterations) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'Maximum iterations reached');\n\t\t\t\t}\n\n\t\t\t\tconst actions = await createEngineRequests(modelResponse, itemIndex, tools);\n\n\t\t\t\treturn {\n\t\t\t\t\tactions,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tpreviousRequests: buildSteps(response, itemIndex),\n\t\t\t\t\t\titerationCount: currentIteration,\n\t\t\t\t\t},\n\t\t\t\t};\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} as INodeExecutionData);\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\n\t\t\tif ('actions' in response) {\n\t\t\t\tif (!request) {\n\t\t\t\t\trequest = {\n\t\t\t\t\t\tactions: response.actions,\n\t\t\t\t\t\tmetadata: response.metadata,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\trequest.actions.push(...response.actions);\n\t\t\t\t}\n\t\t\t\treturn;\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: INodeExecutionData = {\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\t// Check if we have any Request objects (tool calls)\n\tif (request) {\n\t\treturn request;\n\t}\n\n\t// Otherwise return execution data\n\treturn [returnData];\n}\nasync function loadChatHistory(\n\tmemory: BaseChatMemory,\n\tmodel: BaseChatModel,\n\tmaxTokensFromMemory?: number,\n): Promise<BaseMessage[]> {\n\tconst memoryVariables = await memory.loadMemoryVariables({});\n\tlet chatHistory = memoryVariables['chat_history'] as BaseMessage[];\n\n\tif (maxTokensFromMemory) {\n\t\tchatHistory = await trimMessages(chatHistory, {\n\t\t\tstrategy: 'last',\n\t\t\tmaxTokens: maxTokensFromMemory,\n\t\t\ttokenCounter: model,\n\t\t\tincludeSystem: true,\n\t\t\tstartOn: 'human',\n\t\t\tallowPartial: true,\n\t\t});\n\t}\n\n\treturn chatHistory;\n}\n"],"mappings":"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","names":["step","assert","outputParser","response","omit"]}
|
|
@@ -102,6 +102,10 @@ const nodeProperties = [
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
},
|
|
105
|
+
{
|
|
106
|
+
...import_descriptions.textFromGuardrailsNode,
|
|
107
|
+
displayOptions: { show: { promptType: ["guardrails"], "@version": [{ _cnd: { gte: 1.5 } }] } }
|
|
108
|
+
},
|
|
105
109
|
{
|
|
106
110
|
...import_descriptions.textFromPreviousNode,
|
|
107
111
|
displayOptions: { show: { promptType: ["auto"], "@version": [{ _cnd: { gte: 1.5 } }] } }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/config.ts"],"sourcesContent":["import {\n\tAIMessagePromptTemplate,\n\tHumanMessagePromptTemplate,\n\tSystemMessagePromptTemplate,\n} from '@langchain/core/prompts';\nimport type { IDataObject, INodeInputConfiguration, INodeProperties } from 'n8n-workflow';\nimport { NodeConnectionTypes } from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\n/**\n * Dynamic input configuration generation based on node parameters\n */\nexport function getInputs(parameters: IDataObject) {\n\tconst inputs: INodeInputConfiguration[] = [\n\t\t{ displayName: '', type: 'main' },\n\t\t{\n\t\t\tdisplayName: 'Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tconst needsFallback = parameters?.needsFallback;\n\n\tif (needsFallback === true) {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Fallback Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t});\n\t}\n\n\t// If `hasOutputParser` is undefined it must be version 1.3 or earlier so we\n\t// always add the output parser input\n\tconst hasOutputParser = parameters?.hasOutputParser;\n\tif (hasOutputParser === undefined || hasOutputParser === true) {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Output Parser',\n\t\t\ttype: 'ai_outputParser',\n\t\t\tmaxConnections: 1,\n\t\t\trequired: false,\n\t\t});\n\t}\n\n\treturn inputs;\n}\n\n/**\n * Node properties configuration\n */\nexport const nodeProperties: INodeProperties[] = [\n\tgetTemplateNoticeField(1978),\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.input }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.chat_input }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1.1, 1.2],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.chatInput }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...promptTypeOptions,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.2, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...textFromPreviousNode,\n\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.5 } }] } },\n\t},\n\t{\n\t\tdisplayName: 'Prompt (User Message)',\n\t\tname: 'text',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '',\n\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\ttypeOptions: {\n\t\t\trows: 2,\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tpromptType: ['define'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Require Specific Output Format',\n\t\tname: 'hasOutputParser',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tnoDataExpression: true,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Enable Fallback Model',\n\t\tname: 'needsFallback',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tnoDataExpression: true,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Chat Messages (if Using a Chat Model)',\n\t\tname: 'messages',\n\t\ttype: 'fixedCollection',\n\t\ttypeOptions: {\n\t\t\tmultipleValues: true,\n\t\t},\n\t\tdefault: {},\n\t\tplaceholder: 'Add prompt',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'messageValues',\n\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\tvalues: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Type Name or ID',\n\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'AI',\n\t\t\t\t\t\t\t\tvalue: AIMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'System',\n\t\t\t\t\t\t\t\tvalue: SystemMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'User',\n\t\t\t\t\t\t\t\tvalue: HumanMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: SystemMessagePromptTemplate.lc_name(),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Message Type',\n\t\t\t\t\t\tname: 'messageType',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\ttype: [HumanMessagePromptTemplate.lc_name()],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Simple text message',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Image (Binary)',\n\t\t\t\t\t\t\t\tvalue: 'imageBinary',\n\t\t\t\t\t\t\t\tdescription: 'Process the binary input from the previous node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Image (URL)',\n\t\t\t\t\t\t\t\tvalue: 'imageUrl',\n\t\t\t\t\t\t\t\tdescription: 'Process the image from the specified URL',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image Data Field Name',\n\t\t\t\t\t\tname: 'binaryImageDataKey',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: 'data',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"The name of the field in the chain's input that contains the binary image file to be processed\",\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image URL',\n\t\t\t\t\t\tname: 'imageUrl',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdescription: 'URL to the image to be processed',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tmessageType: ['imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image Details',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Control how the model processes the image and generates its textual understanding',\n\t\t\t\t\t\tname: 'imageDetail',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\ttype: [HumanMessagePromptTemplate.lc_name()],\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary', 'imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Auto',\n\t\t\t\t\t\t\t\tvalue: 'auto',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Model will use the auto setting which will look at the image input size and decide if it should use the low or high setting',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Low',\n\t\t\t\t\t\t\t\tvalue: 'low',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'The model will receive a low-res 512px x 512px version of the image, and represent the image with a budget of 65 tokens. This allows the API to return faster responses and consume fewer input tokens for use cases that do not require high detail.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'High',\n\t\t\t\t\t\t\t\tvalue: 'high',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Allows the model to see the low res image and then creates detailed crops of input images as 512px squares based on the input image size. Each of the detailed crops uses twice the token budget (65 tokens) for a total of 129 tokens.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'auto',\n\t\t\t\t\t},\n\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Message',\n\t\t\t\t\t\tname: 'message',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary', 'imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n\tgetBatchingOptionFields({\n\t\tshow: {\n\t\t\t'@version': [{ _cnd: { gte: 1.7 } }],\n\t\t},\n\t}),\n\t{\n\t\tdisplayName: `Connect an <a data-action='openSelectiveNodeCreator' data-action-parameter-connectiontype='${NodeConnectionTypes.AiOutputParser}'>output parser</a> on the canvas to specify the output format you require`,\n\t\tname: 'notice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\thasOutputParser: [true],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName:\n\t\t\t'Connect an additional language model on the canvas to use it as a fallback if the main model fails',\n\t\tname: 'fallbackNotice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tneedsFallback: [true],\n\t\t\t},\n\t\t},\n\t},\n];\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/config.ts"],"sourcesContent":["import {\n\tAIMessagePromptTemplate,\n\tHumanMessagePromptTemplate,\n\tSystemMessagePromptTemplate,\n} from '@langchain/core/prompts';\nimport type { IDataObject, INodeInputConfiguration, INodeProperties } from 'n8n-workflow';\nimport { NodeConnectionTypes } from 'n8n-workflow';\n\nimport {\n\tpromptTypeOptions,\n\ttextFromGuardrailsNode,\n\ttextFromPreviousNode,\n} from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\n/**\n * Dynamic input configuration generation based on node parameters\n */\nexport function getInputs(parameters: IDataObject) {\n\tconst inputs: INodeInputConfiguration[] = [\n\t\t{ displayName: '', type: 'main' },\n\t\t{\n\t\t\tdisplayName: 'Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tconst needsFallback = parameters?.needsFallback;\n\n\tif (needsFallback === true) {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Fallback Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t});\n\t}\n\n\t// If `hasOutputParser` is undefined it must be version 1.3 or earlier so we\n\t// always add the output parser input\n\tconst hasOutputParser = parameters?.hasOutputParser;\n\tif (hasOutputParser === undefined || hasOutputParser === true) {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Output Parser',\n\t\t\ttype: 'ai_outputParser',\n\t\t\tmaxConnections: 1,\n\t\t\trequired: false,\n\t\t});\n\t}\n\n\treturn inputs;\n}\n\n/**\n * Node properties configuration\n */\nexport const nodeProperties: INodeProperties[] = [\n\tgetTemplateNoticeField(1978),\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.input }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.chat_input }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1.1, 1.2],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Prompt',\n\t\tname: 'prompt',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '={{ $json.chatInput }}',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...promptTypeOptions,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.2, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...textFromGuardrailsNode,\n\t\tdisplayOptions: { show: { promptType: ['guardrails'], '@version': [{ _cnd: { gte: 1.5 } }] } },\n\t},\n\t{\n\t\t...textFromPreviousNode,\n\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.5 } }] } },\n\t},\n\t{\n\t\tdisplayName: 'Prompt (User Message)',\n\t\tname: 'text',\n\t\ttype: 'string',\n\t\trequired: true,\n\t\tdefault: '',\n\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\ttypeOptions: {\n\t\t\trows: 2,\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tpromptType: ['define'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Require Specific Output Format',\n\t\tname: 'hasOutputParser',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tnoDataExpression: true,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Enable Fallback Model',\n\t\tname: 'needsFallback',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tnoDataExpression: true,\n\t\tdisplayOptions: {\n\t\t\thide: {\n\t\t\t\t'@version': [1, 1.1, 1.3],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Chat Messages (if Using a Chat Model)',\n\t\tname: 'messages',\n\t\ttype: 'fixedCollection',\n\t\ttypeOptions: {\n\t\t\tmultipleValues: true,\n\t\t},\n\t\tdefault: {},\n\t\tplaceholder: 'Add prompt',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'messageValues',\n\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\tvalues: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Type Name or ID',\n\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'AI',\n\t\t\t\t\t\t\t\tvalue: AIMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'System',\n\t\t\t\t\t\t\t\tvalue: SystemMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'User',\n\t\t\t\t\t\t\t\tvalue: HumanMessagePromptTemplate.lc_name(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: SystemMessagePromptTemplate.lc_name(),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Message Type',\n\t\t\t\t\t\tname: 'messageType',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\ttype: [HumanMessagePromptTemplate.lc_name()],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Text',\n\t\t\t\t\t\t\t\tvalue: 'text',\n\t\t\t\t\t\t\t\tdescription: 'Simple text message',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Image (Binary)',\n\t\t\t\t\t\t\t\tvalue: 'imageBinary',\n\t\t\t\t\t\t\t\tdescription: 'Process the binary input from the previous node',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Image (URL)',\n\t\t\t\t\t\t\t\tvalue: 'imageUrl',\n\t\t\t\t\t\t\t\tdescription: 'Process the image from the specified URL',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'text',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image Data Field Name',\n\t\t\t\t\t\tname: 'binaryImageDataKey',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: 'data',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"The name of the field in the chain's input that contains the binary image file to be processed\",\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image URL',\n\t\t\t\t\t\tname: 'imageUrl',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdescription: 'URL to the image to be processed',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tmessageType: ['imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Image Details',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Control how the model processes the image and generates its textual understanding',\n\t\t\t\t\t\tname: 'imageDetail',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\ttype: [HumanMessagePromptTemplate.lc_name()],\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary', 'imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Auto',\n\t\t\t\t\t\t\t\tvalue: 'auto',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Model will use the auto setting which will look at the image input size and decide if it should use the low or high setting',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Low',\n\t\t\t\t\t\t\t\tvalue: 'low',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'The model will receive a low-res 512px x 512px version of the image, and represent the image with a budget of 65 tokens. This allows the API to return faster responses and consume fewer input tokens for use cases that do not require high detail.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'High',\n\t\t\t\t\t\t\t\tvalue: 'high',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Allows the model to see the low res image and then creates detailed crops of input images as 512px squares based on the input image size. Each of the detailed crops uses twice the token budget (65 tokens) for a total of 129 tokens.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdefault: 'auto',\n\t\t\t\t\t},\n\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Message',\n\t\t\t\t\t\tname: 'message',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\tmessageType: ['imageBinary', 'imageUrl'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t},\n\tgetBatchingOptionFields({\n\t\tshow: {\n\t\t\t'@version': [{ _cnd: { gte: 1.7 } }],\n\t\t},\n\t}),\n\t{\n\t\tdisplayName: `Connect an <a data-action='openSelectiveNodeCreator' data-action-parameter-connectiontype='${NodeConnectionTypes.AiOutputParser}'>output parser</a> on the canvas to specify the output format you require`,\n\t\tname: 'notice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\thasOutputParser: [true],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName:\n\t\t\t'Connect an additional language model on the canvas to use it as a fallback if the main model fails',\n\t\tname: 'fallbackNotice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tneedsFallback: [true],\n\t\t\t},\n\t\t},\n\t},\n];\n"],"mappings":"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","names":[]}
|
|
@@ -117,6 +117,12 @@ class ChainRetrievalQa {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
|
+
{
|
|
121
|
+
...import_descriptions.textFromGuardrailsNode,
|
|
122
|
+
displayOptions: {
|
|
123
|
+
show: { promptType: ["guardrails"], "@version": [{ _cnd: { gte: 1.4 } }] }
|
|
124
|
+
}
|
|
125
|
+
},
|
|
120
126
|
{
|
|
121
127
|
...import_descriptions.textFromPreviousNode,
|
|
122
128
|
displayOptions: { show: { promptType: ["auto"], "@version": [{ _cnd: { gte: 1.4 } }] } }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import { NodeConnectionTypes, parseErrorMetadata, sleep } from 'n8n-workflow';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { INPUT_TEMPLATE_KEY, LEGACY_INPUT_TEMPLATE_KEY, systemPromptOption } from './constants';\nimport { processItem } from './processItem';\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tgetBatchingOptionFields({\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'options.batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.6 && batchSize >= 1) {\n\t\t\t// Run in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = response.reason;\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\tconst answer = output.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Run for each item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await processItem(this, itemIndex);\n\t\t\t\t\tconst answer = response.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import { NodeConnectionTypes, parseErrorMetadata, sleep } from 'n8n-workflow';\nimport {\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport {\n\tpromptTypeOptions,\n\ttextFromGuardrailsNode,\n\ttextFromPreviousNode,\n} from '@utils/descriptions';\nimport { getBatchingOptionFields, getTemplateNoticeField } from '@utils/sharedFields';\n\nimport { INPUT_TEMPLATE_KEY, LEGACY_INPUT_TEMPLATE_KEY, systemPromptOption } from './constants';\nimport { processItem } from './processItem';\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromGuardrailsNode,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: { promptType: ['guardrails'], '@version': [{ _cnd: { gte: 1.4 } }] },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tgetBatchingOptionFields({\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'options.batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.6 && batchSize >= 1) {\n\t\t\t// Run in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = response.reason;\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\tconst answer = output.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Run for each item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await processItem(this, itemIndex);\n\t\t\t\t\tconst answer = response.answer as string;\n\t\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
|