fix(Call n8n Workflow Tool Node): Support concurrent invocations of the tool (#13526)

Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
Charlie Kolb
2025-02-26 16:23:31 +01:00
committed by GitHub
parent 24a38b99a1
commit 5334661b76
15 changed files with 171 additions and 86 deletions

View File

@@ -1,6 +1,6 @@
import { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';
import { createMockExecuteFunction } from 'n8n-nodes-base/test/nodes/Helpers';
import type { INode } from 'n8n-workflow';
import type { INode, ISupplyDataFunctions } from 'n8n-workflow';
import { z } from 'zod';
import { N8nTool } from './N8nTool';
@@ -20,7 +20,7 @@ describe('Test N8nTool wrapper as DynamicStructuredTool', () => {
it('should wrap a tool', () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -39,7 +39,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should convert the tool to a dynamic tool', () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -58,7 +58,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should format fallback description correctly', () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -86,7 +86,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should handle empty parameter list correctly', () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -103,7 +103,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should parse correct parameters', async () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -127,7 +127,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should recover when 1 parameter is passed directly', async () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',
@@ -150,7 +150,7 @@ describe('Test N8nTool wrapper - DynamicTool fallback', () => {
it('should recover when JS object is passed instead of JSON', async () => {
const func = jest.fn();
const ctx = createMockExecuteFunction({}, mockNode);
const ctx = createMockExecuteFunction<ISupplyDataFunctions>({}, mockNode);
const tool = new N8nTool(ctx, {
name: 'Dummy Tool',

View File

@@ -1,7 +1,7 @@
import { DynamicTool, type Tool } from '@langchain/core/tools';
import { createMockExecuteFunction } from 'n8n-nodes-base/test/nodes/Helpers';
import { NodeOperationError } from 'n8n-workflow';
import type { IExecuteFunctions, INode } from 'n8n-workflow';
import type { ISupplyDataFunctions, IExecuteFunctions, INode } from 'n8n-workflow';
import { z } from 'zod';
import { escapeSingleCurlyBrackets, getConnectedTools } from '../helpers';
@@ -171,7 +171,7 @@ describe('getConnectedTools', () => {
mockExecuteFunctions = createMockExecuteFunction({}, mockNode);
mockN8nTool = new N8nTool(mockExecuteFunctions, {
mockN8nTool = new N8nTool(mockExecuteFunctions as unknown as ISupplyDataFunctions, {
name: 'Dummy Tool',
description: 'A dummy tool for testing',
func: jest.fn(),