mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
fix(AI Agent Node): Preserve intermediateSteps when using output parser with non-tool agent (#11363)
This commit is contained in:
@@ -251,7 +251,7 @@ export class Agent implements INodeType {
|
|||||||
icon: 'fa:robot',
|
icon: 'fa:robot',
|
||||||
iconColor: 'black',
|
iconColor: 'black',
|
||||||
group: ['transform'],
|
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.',
|
description: 'Generates an action plan and executes it. Can use external tools.',
|
||||||
subtitle:
|
subtitle:
|
||||||
"={{ { toolsAgent: 'Tools Agent', conversationalAgent: 'Conversational Agent', openAiFunctionsAgent: 'OpenAI Functions Agent', reActAgent: 'ReAct Agent', sqlAgent: 'SQL Agent', planAndExecuteAgent: 'Plan and Execute Agent' }[$parameter.agent] }}",
|
"={{ { toolsAgent: 'Tools Agent', conversationalAgent: 'Conversational Agent', openAiFunctionsAgent: 'OpenAI Functions Agent', reActAgent: 'ReAct Agent', sqlAgent: 'SQL Agent', planAndExecuteAgent: 'Plan and Execute Agent' }[$parameter.agent] }}",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
||||||
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
||||||
import { getTracingConfig } from '../../../../../utils/tracing';
|
import { getTracingConfig } from '../../../../../utils/tracing';
|
||||||
|
import { extractParsedOutput } from '../utils';
|
||||||
|
|
||||||
export async function conversationalAgentExecute(
|
export async function conversationalAgentExecute(
|
||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
@@ -102,12 +103,12 @@ export async function conversationalAgentExecute(
|
|||||||
input = (await prompt.invoke({ input })).value;
|
input = (await prompt.invoke({ input })).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await agentExecutor
|
const response = await agentExecutor
|
||||||
.withConfig(getTracingConfig(this))
|
.withConfig(getTracingConfig(this))
|
||||||
.invoke({ input, outputParsers });
|
.invoke({ input, outputParsers });
|
||||||
|
|
||||||
if (outputParser) {
|
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 });
|
returnData.push({ json: response });
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import { getConnectedTools, getPromptInputByType } from '../../../../../utils/helpers';
|
import { getConnectedTools, getPromptInputByType } from '../../../../../utils/helpers';
|
||||||
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
||||||
import { getTracingConfig } from '../../../../../utils/tracing';
|
import { getTracingConfig } from '../../../../../utils/tracing';
|
||||||
|
import { extractParsedOutput } from '../utils';
|
||||||
|
|
||||||
export async function openAiFunctionsAgentExecute(
|
export async function openAiFunctionsAgentExecute(
|
||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
@@ -103,12 +104,12 @@ export async function openAiFunctionsAgentExecute(
|
|||||||
input = (await prompt.invoke({ input })).value;
|
input = (await prompt.invoke({ input })).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await agentExecutor
|
const response = await agentExecutor
|
||||||
.withConfig(getTracingConfig(this))
|
.withConfig(getTracingConfig(this))
|
||||||
.invoke({ input, outputParsers });
|
.invoke({ input, outputParsers });
|
||||||
|
|
||||||
if (outputParser) {
|
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 });
|
returnData.push({ json: response });
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { getConnectedTools, getPromptInputByType } from '../../../../../utils/he
|
|||||||
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
||||||
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
||||||
import { getTracingConfig } from '../../../../../utils/tracing';
|
import { getTracingConfig } from '../../../../../utils/tracing';
|
||||||
|
import { extractParsedOutput } from '../utils';
|
||||||
|
|
||||||
export async function planAndExecuteAgentExecute(
|
export async function planAndExecuteAgentExecute(
|
||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
@@ -79,12 +80,12 @@ export async function planAndExecuteAgentExecute(
|
|||||||
input = (await prompt.invoke({ input })).value;
|
input = (await prompt.invoke({ input })).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await agentExecutor
|
const response = await agentExecutor
|
||||||
.withConfig(getTracingConfig(this))
|
.withConfig(getTracingConfig(this))
|
||||||
.invoke({ input, outputParsers });
|
.invoke({ input, outputParsers });
|
||||||
|
|
||||||
if (outputParser) {
|
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 });
|
returnData.push({ json: response });
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
import { getOptionalOutputParsers } from '../../../../../utils/output_parsers/N8nOutputParser';
|
||||||
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
import { throwIfToolSchema } from '../../../../../utils/schemaParsing';
|
||||||
import { getTracingConfig } from '../../../../../utils/tracing';
|
import { getTracingConfig } from '../../../../../utils/tracing';
|
||||||
|
import { extractParsedOutput } from '../utils';
|
||||||
|
|
||||||
export async function reActAgentAgentExecute(
|
export async function reActAgentAgentExecute(
|
||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
@@ -103,12 +104,12 @@ export async function reActAgentAgentExecute(
|
|||||||
input = (await prompt.invoke({ input })).value;
|
input = (await prompt.invoke({ input })).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await agentExecutor
|
const response = await agentExecutor
|
||||||
.withConfig(getTracingConfig(this))
|
.withConfig(getTracingConfig(this))
|
||||||
.invoke({ input, outputParsers });
|
.invoke({ input, outputParsers });
|
||||||
|
|
||||||
if (outputParser) {
|
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 });
|
returnData.push({ json: response });
|
||||||
|
|||||||
@@ -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<unknown>,
|
||||||
|
output: string,
|
||||||
|
): Promise<Record<string, unknown> | undefined> {
|
||||||
|
const parsedOutput = (await outputParser.parse(output)) as {
|
||||||
|
output: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user