mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
fix(AI Agent Node): Preserve intermediateSteps
when using output parser with non-tool agent (#11363)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Benchmark Docker Image CI / build (push) Waiting to run
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Benchmark Docker Image CI / build (push) Waiting to run
This commit is contained in:
parent
197a1264d1
commit
e61a8535aa
|
@ -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] }}",
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue