feat(editor): Drop response wrapper requirement from Subworkflow Tool output (#11785)

Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
Charlie Kolb
2024-11-22 10:17:45 +01:00
committed by GitHub
parent 89b4807243
commit cd3598aaab

View File

@@ -36,7 +36,7 @@ export class ToolWorkflow implements INodeType {
name: 'toolWorkflow', name: 'toolWorkflow',
icon: 'fa:network-wired', icon: 'fa:network-wired',
group: ['transform'], group: ['transform'],
version: [1, 1.1, 1.2], version: [1, 1.1, 1.2, 1.3],
description: 'Uses another n8n workflow as a tool. Allows packaging any n8n node(s) as a tool.', description: 'Uses another n8n workflow as a tool. Allows packaging any n8n node(s) as a tool.',
defaults: { defaults: {
name: 'Call n8n Workflow Tool', name: 'Call n8n Workflow Tool',
@@ -200,6 +200,11 @@ export class ToolWorkflow implements INodeType {
hint: 'The field in the last-executed node of the workflow that contains the response', hint: 'The field in the last-executed node of the workflow that contains the response',
description: description:
'Where to find the data that this tool should return. n8n will look in the output of the last-executed node of the workflow for a field with this name, and return its value.', 'Where to find the data that this tool should return. n8n will look in the output of the last-executed node of the workflow for a field with this name, and return its value.',
displayOptions: {
show: {
'@version': [{ _cnd: { lt: 1.3 } }],
},
},
}, },
{ {
displayName: 'Extra Workflow Inputs', displayName: 'Extra Workflow Inputs',
@@ -376,19 +381,6 @@ export class ToolWorkflow implements INodeType {
runManager?: CallbackManagerForToolRun, runManager?: CallbackManagerForToolRun,
): Promise<string> => { ): Promise<string> => {
const source = this.getNodeParameter('source', itemIndex) as string; const source = this.getNodeParameter('source', itemIndex) as string;
const responsePropertyName = this.getNodeParameter(
'responsePropertyName',
itemIndex,
) as string;
if (!responsePropertyName) {
throw new NodeOperationError(this.getNode(), "Field to return can't be empty", {
itemIndex,
description:
'Enter the name of a field in the last node of the workflow that contains the response to return',
});
}
const workflowInfo: IExecuteWorkflowInfo = {}; const workflowInfo: IExecuteWorkflowInfo = {};
if (source === 'database') { if (source === 'database') {
// Read workflow from database // Read workflow from database
@@ -467,17 +459,13 @@ export class ToolWorkflow implements INodeType {
throw new NodeOperationError(this.getNode(), error as Error); throw new NodeOperationError(this.getNode(), error as Error);
} }
const response: string | undefined = get(receivedData, [ const response: string | undefined = get(receivedData, 'data[0][0].json') as
'data', | string
0, | undefined;
0,
'json',
responsePropertyName,
]) as string | undefined;
if (response === undefined) { if (response === undefined) {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),
`There was an error: "The workflow did not return an item with the property '${responsePropertyName}'"`, 'There was an error: "The workflow did not return a response"',
); );
} }
@@ -531,12 +519,10 @@ export class ToolWorkflow implements INodeType {
if (executionError) { if (executionError) {
void this.addOutputData(NodeConnectionType.AiTool, index, executionError, metadata); void this.addOutputData(NodeConnectionType.AiTool, index, executionError, metadata);
} else { } else {
void this.addOutputData( // Output always needs to be an object
NodeConnectionType.AiTool, // so we try to parse the response as JSON and if it fails we just return the string wrapped in an object
index, const json = jsonParse<IDataObject>(response, { fallbackValue: { response } });
[[{ json: { response } }]], void this.addOutputData(NodeConnectionType.AiTool, index, [[{ json }]], metadata);
metadata,
);
} }
return response; return response;
}; };