n8n-nodes-fasttext-language-detector 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -201,25 +201,34 @@ class FastTextLanguageDetector {
|
|
|
201
201
|
try {
|
|
202
202
|
// Используем require для загрузки CommonJS модуля
|
|
203
203
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
204
|
-
const
|
|
205
|
-
resolve(
|
|
204
|
+
const FastText = require('fasttext.js');
|
|
205
|
+
resolve(FastText);
|
|
206
206
|
}
|
|
207
207
|
catch (error) {
|
|
208
208
|
reject(error);
|
|
209
209
|
}
|
|
210
210
|
});
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
(fastTextModule.default && fastTextModule.default.
|
|
215
|
-
|
|
216
|
-
if (!FastTextClassifier || typeof FastTextClassifier !== 'function') {
|
|
211
|
+
// fasttext.js экспортирует класс FastText напрямую
|
|
212
|
+
const FastTextClass = fastTextModule ||
|
|
213
|
+
fastTextModule.default ||
|
|
214
|
+
(fastTextModule.default && fastTextModule.default.default);
|
|
215
|
+
if (!FastTextClass || typeof FastTextClass !== 'function') {
|
|
217
216
|
const availableExports = Object.keys(fastTextModule).join(', ');
|
|
218
|
-
throw new n8n_workflow_1.ApplicationError(`Failed to load fastText module:
|
|
217
|
+
throw new n8n_workflow_1.ApplicationError(`Failed to load fastText module: FastText class not found. Available exports: ${availableExports}`, { level: 'error' });
|
|
219
218
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
// Создаем экземпляр FastText с путем к модели
|
|
220
|
+
const fastTextInstance = new FastTextClass({
|
|
221
|
+
loadModel: modelPath,
|
|
222
|
+
predict: {
|
|
223
|
+
mostlikely: topK,
|
|
224
|
+
verbosity: 0,
|
|
225
|
+
normalize: false
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// Загружаем модель
|
|
229
|
+
await fastTextInstance.load();
|
|
230
|
+
model = fastTextInstance;
|
|
231
|
+
FastTextLanguageDetector.modelCache.set(modelPath, fastTextInstance);
|
|
223
232
|
}
|
|
224
233
|
}
|
|
225
234
|
catch (error) {
|
|
@@ -265,19 +274,48 @@ class FastTextLanguageDetector {
|
|
|
265
274
|
throw new n8n_workflow_1.ApplicationError('Model not initialized', { level: 'error' });
|
|
266
275
|
}
|
|
267
276
|
// Определяем язык
|
|
268
|
-
|
|
277
|
+
// fasttext.js возвращает массив массивов [label, probability] или массив объектов
|
|
278
|
+
const predictionsRaw = await model.predict(processedText);
|
|
279
|
+
if (!Array.isArray(predictionsRaw) || predictionsRaw.length === 0) {
|
|
280
|
+
throw new n8n_workflow_1.ApplicationError('No predictions returned from fastText model', { level: 'error' });
|
|
281
|
+
}
|
|
282
|
+
// Преобразуем формат ответа fasttext.js в наш формат
|
|
283
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
284
|
+
const predictions = predictionsRaw.map((pred) => {
|
|
285
|
+
// fasttext.js возвращает либо [label, value], либо объект
|
|
286
|
+
let label;
|
|
287
|
+
let probability;
|
|
288
|
+
if (Array.isArray(pred)) {
|
|
289
|
+
label = String(pred[0] || '');
|
|
290
|
+
probability = Number(pred[1] || 0);
|
|
291
|
+
}
|
|
292
|
+
else if (pred && typeof pred === 'object') {
|
|
293
|
+
label = String(pred.label || pred[0] || '');
|
|
294
|
+
probability = Number(pred.value || pred.probability || pred[1] || 0);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
label = String(pred || '');
|
|
298
|
+
probability = 0;
|
|
299
|
+
}
|
|
300
|
+
// Убираем префикс __label__ если есть
|
|
301
|
+
const cleanLabel = label.replace(/^__label__/, '');
|
|
302
|
+
return {
|
|
303
|
+
label: cleanLabel,
|
|
304
|
+
probability: probability
|
|
305
|
+
};
|
|
306
|
+
});
|
|
269
307
|
// Фильтруем по порогу уверенности
|
|
270
308
|
const filteredPredictions = predictions.filter((pred) => pred.probability >= confidenceThreshold);
|
|
271
309
|
if (filteredPredictions.length === 0) {
|
|
272
310
|
// Если нет предсказаний выше порога, возвращаем лучшее
|
|
273
311
|
const result = {
|
|
274
312
|
...json,
|
|
275
|
-
[outputField]: predictions[0]?.label
|
|
313
|
+
[outputField]: predictions[0]?.label || 'unknown',
|
|
276
314
|
};
|
|
277
315
|
if (includeConfidence) {
|
|
278
316
|
result[`${outputField}Confidence`] = predictions[0]?.probability || 0;
|
|
279
317
|
result[`${outputField}All`] = predictions.map((p) => ({
|
|
280
|
-
language: p.label
|
|
318
|
+
language: p.label || 'unknown',
|
|
281
319
|
confidence: p.probability || 0,
|
|
282
320
|
}));
|
|
283
321
|
}
|
|
@@ -288,7 +326,7 @@ class FastTextLanguageDetector {
|
|
|
288
326
|
const topPrediction = filteredPredictions[0];
|
|
289
327
|
const result = {
|
|
290
328
|
...json,
|
|
291
|
-
[outputField]: topPrediction.label
|
|
329
|
+
[outputField]: topPrediction.label || 'unknown',
|
|
292
330
|
};
|
|
293
331
|
if (includeConfidence) {
|
|
294
332
|
result[`${outputField}Confidence`] = topPrediction.probability || 0;
|