mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(core): Allow community nodes to be used as tools (#14042)
This commit is contained in:
committed by
GitHub
parent
91b27964d8
commit
9d698edceb
@@ -33,10 +33,6 @@ class CommunityPackagesConfig {
|
||||
/** Whether to reinstall any missing community packages */
|
||||
@Env('N8N_REINSTALL_MISSING_PACKAGES')
|
||||
reinstallMissing: boolean = false;
|
||||
|
||||
/** Whether to allow community packages as tools for AI agents */
|
||||
@Env('N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE')
|
||||
allowToolUsage: boolean = false;
|
||||
}
|
||||
|
||||
@Config
|
||||
|
||||
@@ -118,7 +118,6 @@ describe('GlobalConfig', () => {
|
||||
enabled: true,
|
||||
registry: 'https://registry.npmjs.org',
|
||||
reinstallMissing: false,
|
||||
allowToolUsage: false,
|
||||
},
|
||||
errorTriggerType: 'n8n-nodes-base.errorTrigger',
|
||||
include: [],
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { GlobalConfig } from '@n8n/config';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { RoutingNode, UnrecognizedNodeTypeError } from 'n8n-core';
|
||||
import type {
|
||||
@@ -12,14 +11,11 @@ import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { NodeTypes } from '@/node-types';
|
||||
|
||||
describe('NodeTypes', () => {
|
||||
const globalConfig = mock<GlobalConfig>({
|
||||
nodes: { communityPackages: { allowToolUsage: false } },
|
||||
});
|
||||
const loadNodesAndCredentials = mock<LoadNodesAndCredentials>({
|
||||
convertNodeToAiTool: LoadNodesAndCredentials.prototype.convertNodeToAiTool,
|
||||
});
|
||||
|
||||
const nodeTypes: NodeTypes = new NodeTypes(globalConfig, loadNodesAndCredentials);
|
||||
const nodeTypes: NodeTypes = new NodeTypes(loadNodesAndCredentials);
|
||||
|
||||
const nonVersionedNode: LoadedClass<INodeType> = {
|
||||
sourcePath: '',
|
||||
@@ -117,7 +113,6 @@ describe('NodeTypes', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
globalConfig.nodes.communityPackages.allowToolUsage = false;
|
||||
loadNodesAndCredentials.loaded.nodes = {};
|
||||
});
|
||||
|
||||
@@ -173,14 +168,7 @@ describe('NodeTypes', () => {
|
||||
expect(result.description.outputs).toEqual(['ai_tool']);
|
||||
});
|
||||
|
||||
it('should throw when a node-type is requested as tool, but is a community package', () => {
|
||||
expect(() => nodeTypes.getByNameAndVersion('n8n-nodes-community.testNodeTool')).toThrow(
|
||||
'Unrecognized node type: n8n-nodes-community.testNodeTool',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return a tool node-type from a community node, when requested as tool', () => {
|
||||
globalConfig.nodes.communityPackages.allowToolUsage = true;
|
||||
const result = nodeTypes.getByNameAndVersion('n8n-nodes-community.testNodeTool');
|
||||
expect(result).not.toEqual(toolSupportingNode.type);
|
||||
expect(result.description.name).toEqual('n8n-nodes-community.testNodeTool');
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import { Service } from '@n8n/di';
|
||||
import type { NeededNodeType } from '@n8n/task-runner';
|
||||
import type { Dirent } from 'fs';
|
||||
@@ -14,10 +13,7 @@ import { shouldAssignExecuteMethod } from './utils';
|
||||
|
||||
@Service()
|
||||
export class NodeTypes implements INodeTypes {
|
||||
constructor(
|
||||
private readonly globalConfig: GlobalConfig,
|
||||
private readonly loadNodesAndCredentials: LoadNodesAndCredentials,
|
||||
) {}
|
||||
constructor(private readonly loadNodesAndCredentials: LoadNodesAndCredentials) {}
|
||||
|
||||
/**
|
||||
* Variant of `getByNameAndVersion` that includes the node's source path, used to locate a node's translations.
|
||||
@@ -39,14 +35,10 @@ export class NodeTypes implements INodeTypes {
|
||||
getByNameAndVersion(nodeType: string, version?: number): INodeType {
|
||||
const origType = nodeType;
|
||||
|
||||
const { communityPackages } = this.globalConfig.nodes;
|
||||
const allowToolUsage = communityPackages.allowToolUsage
|
||||
? true
|
||||
: nodeType.startsWith('n8n-nodes-base');
|
||||
const toolRequested = nodeType.endsWith('Tool');
|
||||
|
||||
// Make sure the nodeType to actually get from disk is the un-wrapped type
|
||||
if (allowToolUsage && toolRequested) {
|
||||
if (toolRequested) {
|
||||
nodeType = nodeType.replace(/Tool$/, '');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user