diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/Agent.node.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/Agent.node.ts index 295eaa9296..0b27456db6 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/Agent.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/Agent.node.ts @@ -251,7 +251,7 @@ export class Agent implements INodeType { icon: 'fa:robot', iconColor: 'black', group: ['transform'], - version: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6], + version: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7], description: 'Generates an action plan and executes it. Can use external tools.', subtitle: "={{ { toolsAgent: 'Tools Agent', conversationalAgent: 'Conversational Agent', openAiFunctionsAgent: 'OpenAI Functions Agent', reActAgent: 'ReAct Agent', sqlAgent: 'SQL Agent', planAndExecuteAgent: 'Plan and Execute Agent' }[$parameter.agent] }}", diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ConversationalAgent/execute.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ConversationalAgent/execute.ts index d171efe95f..365fce3bf0 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ConversationalAgent/execute.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ConversationalAgent/execute.ts @@ -14,6 +14,7 @@ import { import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser'; import { throwIfToolSchema } from '../../../../../utils/schemaParsing'; import { getTracingConfig } from '../../../../../utils/tracing'; +import { extractParsedOutput } from '../utils'; export async function conversationalAgentExecute( this: IExecuteFunctions, @@ -102,12 +103,12 @@ export async function conversationalAgentExecute( input = (await prompt.invoke({ input })).value; } - let response = await agentExecutor + const response = await agentExecutor .withConfig(getTracingConfig(this)) .invoke({ input, outputParsers }); if (outputParser) { - response = { output: await outputParser.parse(response.output as string) }; + response.output = await extractParsedOutput(this, outputParser, response.output as string); } returnData.push({ json: response }); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.ts index 0518234c29..a9b324678c 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.ts @@ -15,6 +15,7 @@ import { import { getConnectedTools, getPromptInputByType } from '../../../../../utils/helpers'; import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser'; import { getTracingConfig } from '../../../../../utils/tracing'; +import { extractParsedOutput } from '../utils'; export async function openAiFunctionsAgentExecute( this: IExecuteFunctions, @@ -103,12 +104,12 @@ export async function openAiFunctionsAgentExecute( input = (await prompt.invoke({ input })).value; } - let response = await agentExecutor + const response = await agentExecutor .withConfig(getTracingConfig(this)) .invoke({ input, outputParsers }); if (outputParser) { - response = { output: await outputParser.parse(response.output as string) }; + response.output = await extractParsedOutput(this, outputParser, response.output as string); } returnData.push({ json: response }); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.ts index f10207c715..9425caaf84 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.ts @@ -14,6 +14,7 @@ import { getConnectedTools, getPromptInputByType } from '../../../../../utils/he import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser'; import { throwIfToolSchema } from '../../../../../utils/schemaParsing'; import { getTracingConfig } from '../../../../../utils/tracing'; +import { extractParsedOutput } from '../utils'; export async function planAndExecuteAgentExecute( this: IExecuteFunctions, @@ -79,12 +80,12 @@ export async function planAndExecuteAgentExecute( input = (await prompt.invoke({ input })).value; } - let response = await agentExecutor + const response = await agentExecutor .withConfig(getTracingConfig(this)) .invoke({ input, outputParsers }); if (outputParser) { - response = { output: await outputParser.parse(response.output as string) }; + response.output = await extractParsedOutput(this, outputParser, response.output as string); } returnData.push({ json: response }); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ReActAgent/execute.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ReActAgent/execute.ts index 5707baa9d6..429adfad21 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ReActAgent/execute.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ReActAgent/execute.ts @@ -19,6 +19,7 @@ import { import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser'; import { throwIfToolSchema } from '../../../../../utils/schemaParsing'; import { getTracingConfig } from '../../../../../utils/tracing'; +import { extractParsedOutput } from '../utils'; export async function reActAgentAgentExecute( this: IExecuteFunctions, @@ -103,12 +104,12 @@ export async function reActAgentAgentExecute( input = (await prompt.invoke({ input })).value; } - let response = await agentExecutor + const response = await agentExecutor .withConfig(getTracingConfig(this)) .invoke({ input, outputParsers }); if (outputParser) { - response = { output: await outputParser.parse(response.output as string) }; + response.output = await extractParsedOutput(this, outputParser, response.output as string); } returnData.push({ json: response }); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/utils.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/utils.ts new file mode 100644 index 0000000000..da2f666248 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/utils.ts @@ -0,0 +1,19 @@ +import type { BaseOutputParser } from '@langchain/core/output_parsers'; +import type { IExecuteFunctions } from 'n8n-workflow'; + +export async function extractParsedOutput( + ctx: IExecuteFunctions, + outputParser: BaseOutputParser, + output: string, +): Promise | undefined> { + const parsedOutput = (await outputParser.parse(output)) as { + output: Record; + }; + + if (ctx.getNode().typeVersion <= 1.6) { + return parsedOutput; + } + // For 1.7 and above, we try to extract the output from the parsed output + // with fallback to the original output if it's not present + return parsedOutput?.output ?? parsedOutput; +}