diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/AgentTool.node.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/AgentTool.node.ts index 42e88f02d9c..1613315393d 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/AgentTool.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/AgentTool.node.ts @@ -2,6 +2,7 @@ import type { INodeTypeBaseDescription, IVersionedNodeType } from 'n8n-workflow' import { VersionedNodeType } from 'n8n-workflow'; import { AgentToolV2 } from './V2/AgentToolV2.node'; +import { AgentToolV3 } from './V3/AgentToolV3.node'; export class AgentTool extends VersionedNodeType { constructor() { @@ -20,13 +21,14 @@ export class AgentTool extends VersionedNodeType { Tools: ['Other Tools'], }, }, - defaultVersion: 2.2, + defaultVersion: 3, }; const nodeVersions: IVersionedNodeType['nodeVersions'] = { // Should have the same versioning as Agent node // because internal agent logic often checks for node version 2.2: new AgentToolV2(baseDescription), + 3: new AgentToolV3(baseDescription), }; super(nodeVersions, baseDescription); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/V3/AgentToolV3.node.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/V3/AgentToolV3.node.ts new file mode 100644 index 00000000000..71d7b704b92 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/V3/AgentToolV3.node.ts @@ -0,0 +1,91 @@ +import { NodeConnectionTypes } from 'n8n-workflow'; +import type { + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, + INodeTypeBaseDescription, + ISupplyDataFunctions, + EngineResponse, + EngineRequest, +} from 'n8n-workflow'; + +import { textInput, toolDescription } from '@utils/descriptions'; + +import { getInputs } from '../utils'; +import { toolsAgentProperties } from '../agents/ToolsAgent/V3/description'; +import type { RequestResponseMetadata } from '../agents/ToolsAgent/V3/execute'; +import { toolsAgentExecute } from '../agents/ToolsAgent/V3/execute'; + +export class AgentToolV3 implements INodeType { + description: INodeTypeDescription; + constructor(baseDescription: INodeTypeBaseDescription) { + this.description = { + ...baseDescription, + version: [3], + defaults: { + name: 'AI Agent Tool', + color: '#404040', + }, + inputs: `={{ + ((hasOutputParser, needsFallback) => { + ${getInputs.toString()}; + return getInputs(false, hasOutputParser, needsFallback) + })($parameter.hasOutputParser === undefined || $parameter.hasOutputParser === true, $parameter.needsFallback !== undefined && $parameter.needsFallback === true) + }}`, + outputs: [NodeConnectionTypes.AiTool], + properties: [ + toolDescription, + { + ...textInput, + }, + { + displayName: 'Require Specific Output Format', + name: 'hasOutputParser', + type: 'boolean', + default: false, + noDataExpression: true, + }, + { + displayName: `Connect an output parser on the canvas to specify the output format you require`, + name: 'notice', + type: 'notice', + default: '', + displayOptions: { + show: { + hasOutputParser: [true], + }, + }, + }, + { + displayName: 'Enable Fallback Model', + name: 'needsFallback', + type: 'boolean', + default: false, + noDataExpression: true, + }, + { + displayName: + 'Connect an additional language model on the canvas to use it as a fallback if the main model fails', + name: 'fallbackNotice', + type: 'notice', + default: '', + displayOptions: { + show: { + needsFallback: [true], + }, + }, + }, + toolsAgentProperties, + ], + }; + } + + // Automatically wrapped as a tool + async execute( + this: IExecuteFunctions | ISupplyDataFunctions, + response?: EngineResponse, + ): Promise> { + return await toolsAgentExecute.call(this, response); + } +}