feat(core): Implement partial execution for all tool nodes (#15168)

This commit is contained in:
Benjamin Schroth
2025-05-12 12:31:17 +02:00
committed by GitHub
parent d12c7ee87f
commit 8b467e3f56
39 changed files with 1129 additions and 279 deletions

View File

@@ -40,6 +40,7 @@ import type {
INodeIssues,
INodeType,
ITaskStartedData,
AiAgentRequest,
} from 'n8n-workflow';
import {
LoggerProxy as Logger,
@@ -51,6 +52,7 @@ import {
Node,
UnexpectedError,
UserError,
OperationalError,
} from 'n8n-workflow';
import PCancelable from 'p-cancelable';
@@ -72,6 +74,7 @@ import {
isTool,
getNextExecutionIndex,
} from './partial-execution-utils';
import { TOOL_EXECUTOR_NODE_NAME } from './partial-execution-utils/rewire-graph';
import { RoutingNode } from './routing-node';
import { TriggersAndPollers } from './triggers-and-pollers';
@@ -346,6 +349,7 @@ export class WorkflowExecute {
pinData: IPinData = {},
dirtyNodeNames: string[] = [],
destinationNodeName?: string,
agentRequest?: AiAgentRequest,
): PCancelable<IRun> {
// TODO: Refactor the call-site to make `destinationNodeName` a required
// after removing the old partial execution flow.
@@ -354,7 +358,7 @@ export class WorkflowExecute {
'a destinationNodeName is required for the new partial execution flow',
);
const destination = workflow.getNode(destinationNodeName);
let destination = workflow.getNode(destinationNodeName);
assert.ok(
destination,
`Could not find a node with the name ${destinationNodeName} in the workflow.`,
@@ -364,8 +368,15 @@ export class WorkflowExecute {
// Partial execution of nodes as tools
if (isTool(destination, workflow.nodeTypes)) {
graph = rewireGraph(destination, graph);
graph = rewireGraph(destination, graph, agentRequest);
workflow = graph.toWorkflow({ ...workflow });
// Rewire destination node to the virtual agent
const toolExecutorNode = workflow.getNode(TOOL_EXECUTOR_NODE_NAME);
if (!toolExecutorNode) {
throw new OperationalError('ToolExecutor can not be found');
}
destination = toolExecutorNode;
destinationNodeName = toolExecutorNode.name;
} else {
// Edge Case 1:
// Support executing a single node that is not connected to a trigger