UNPKG

n8n-nodes-rckflr-ner

Version:

N8N node for Named Entity Recognition (NER) using Transformer.js

116 lines 5.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NamedEntityRecognition = void 0; const n8n_workflow_1 = require("n8n-workflow"); const transformers_1 = require("@huggingface/transformers"); class NamedEntityRecognition { constructor() { this.description = { displayName: 'Named Entity Recognition', name: 'namedEntityRecognition', icon: 'fa:tags', group: ['ai'], version: 1, description: 'Extracts named entities (like persons, locations, organizations) from text using Transformers.js.', defaults: { name: 'Named Entity Recognition', }, inputs: ["main" /* NodeConnectionType.Main */], outputs: ["main" /* NodeConnectionType.Main */], usableAsTool: true, properties: [ { displayName: 'Input Text', name: 'inputText', type: 'string', typeOptions: { rows: 5, }, default: '', required: true, description: 'The text from which to extract named entities.', placeholder: 'e.g., N8N is a workflow automation tool based in Berlin, developed by Johannes and a great team.', }, { displayName: 'Aggregation Strategy', name: 'aggregationStrategy', type: 'options', options: [ { name: 'None', value: 'none' }, { name: 'Simple (Recommended)', value: 'simple' }, { name: 'First', value: 'first' }, { name: 'Average', value: 'average' }, { name: 'Max', value: 'max' }, ], default: 'simple', description: "Strategy to group token parts (e.g. B-PER, I-PER) into single entities. 'Simple' is often a good default.", }, { displayName: 'Output Field Name', name: 'outputFieldName', type: 'string', default: 'entities', required: true, description: 'The field name where the array of extracted entities will be stored.', }, ], }; } async execute() { const itemIndex = 0; // We will only ever process one item. // Define the model to use const model = 'Xenova/bert-base-NER'; // Get node parameters const outputFieldName = this.getNodeParameter('outputFieldName', itemIndex, 'entities'); const aggregationStrategy = this.getNodeParameter('aggregationStrategy', itemIndex, 'simple'); const inputText = this.getNodeParameter('inputText', itemIndex, ''); if (!inputText || !inputText.trim()) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Input Text parameter is required. Please provide a static value or an expression.'); } // Initialize the pipeline (cache it to avoid reloading) let pipe = NamedEntityRecognition.pipelineCache.get(model); if (!pipe) { try { this.logger.info(`Loading NER model: ${model}`); pipe = await (0, transformers_1.pipeline)('token-classification', model); NamedEntityRecognition.pipelineCache.set(model, pipe); this.logger.info(`NER Model ${model} loaded successfully`); } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load NER model: ${error.message}`); } } // Process the text try { this.logger.info(`Extracting entities from text...`); const pipelineOptions = {}; if (aggregationStrategy && aggregationStrategy !== 'none') { pipelineOptions.aggregation_strategy = aggregationStrategy; } const processedOutput = await pipe(inputText, pipelineOptions); this.logger.info(`Raw NER output: ${JSON.stringify(processedOutput)}`); if (!Array.isArray(processedOutput)) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'NER output is not in the expected array format.'); } const resultJson = {}; resultJson[outputFieldName] = processedOutput; return [this.helpers.returnJsonArray([{ json: resultJson }])]; } catch (error) { if (this.continueOnFail()) { const errorItem = { json: { error: error.message, }, }; return [this.helpers.returnJsonArray([errorItem])]; } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message || String(error)); } } } } exports.NamedEntityRecognition = NamedEntityRecognition; NamedEntityRecognition.pipelineCache = new Map(); //# sourceMappingURL=NamedEntityRecognition.node.js.map