n8n-nodes-vlm 2.0.3 → 2.0.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.
@@ -207,23 +207,23 @@ class VLMComplexityWorkflow {
207
207
  name: 'outputFormat',
208
208
  type: 'options',
209
209
  options: [
210
- {
211
- name: 'Documents Array',
212
- value: 'documents',
213
- description: 'Return classified documents in an array',
214
- },
215
210
  {
216
211
  name: 'Separate Items',
217
212
  value: 'items',
218
- description: 'Return each document as a separate item',
213
+ description: 'Return each document as a separate item (recommended for binary data)',
219
214
  },
220
215
  {
221
216
  name: 'Original Format',
222
217
  value: 'original',
223
218
  description: 'Maintain original input structure with classifications added',
224
219
  },
220
+ {
221
+ name: 'Documents Array',
222
+ value: 'documents',
223
+ description: 'Return classified documents in an array',
224
+ },
225
225
  ],
226
- default: 'documents',
226
+ default: 'items',
227
227
  description: 'How to format the output',
228
228
  },
229
229
  ],
@@ -297,24 +297,76 @@ class VLMComplexityWorkflow {
297
297
  const fieldName = this.getNodeParameter('fieldName', 0);
298
298
  for (let i = 0; i < items.length; i++) {
299
299
  const fieldData = items[i].json[fieldName];
300
+ const extractedDocs = [];
300
301
  if (Array.isArray(fieldData)) {
301
- documents.push(...fieldData);
302
+ extractedDocs.push(...fieldData);
302
303
  }
303
304
  else if (fieldData) {
304
- documents.push(fieldData);
305
+ extractedDocs.push(fieldData);
305
306
  }
307
+ // For each extracted document, also attach binary data if available
308
+ extractedDocs.forEach((doc) => {
309
+ const enhancedDoc = typeof doc === 'object' ? { ...doc } : { content: doc };
310
+ // Extract binary image data from n8n item.binary
311
+ const itemBinary = items[i].binary;
312
+ if (itemBinary) {
313
+ enhancedDoc.metadata = enhancedDoc.metadata || {};
314
+ enhancedDoc.metadata._originalBinary = itemBinary;
315
+ enhancedDoc.metadata._itemIndex = i;
316
+ // Find first image in binary data
317
+ for (const [binaryKey, binaryData] of Object.entries(itemBinary)) {
318
+ const data = binaryData;
319
+ if (data.mimeType && data.mimeType.startsWith('image/')) {
320
+ const base64Data = data.data;
321
+ if (base64Data) {
322
+ enhancedDoc.base64Image = `data:${data.mimeType};base64,${base64Data}`;
323
+ enhancedDoc.metadata._binaryKey = binaryKey;
324
+ this.logger.debug(`Extracted image from binary '${binaryKey}' (${data.mimeType}) for item ${i} (field source)`);
325
+ break;
326
+ }
327
+ }
328
+ }
329
+ }
330
+ documents.push(enhancedDoc);
331
+ });
306
332
  }
307
333
  }
308
334
  else if (documentSource === 'expression') {
309
335
  // Extract from expression
310
336
  for (let i = 0; i < items.length; i++) {
311
337
  const expressionValue = this.getNodeParameter('documentsExpression', i);
338
+ const extractedDocs = [];
312
339
  if (Array.isArray(expressionValue)) {
313
- documents.push(...expressionValue);
340
+ extractedDocs.push(...expressionValue);
314
341
  }
315
342
  else if (expressionValue) {
316
- documents.push(expressionValue);
343
+ extractedDocs.push(expressionValue);
317
344
  }
345
+ // For each extracted document, also attach binary data if available
346
+ extractedDocs.forEach((doc) => {
347
+ const enhancedDoc = typeof doc === 'object' ? { ...doc } : { content: doc };
348
+ // Extract binary image data from n8n item.binary
349
+ const itemBinary = items[i].binary;
350
+ if (itemBinary) {
351
+ enhancedDoc.metadata = enhancedDoc.metadata || {};
352
+ enhancedDoc.metadata._originalBinary = itemBinary;
353
+ enhancedDoc.metadata._itemIndex = i;
354
+ // Find first image in binary data
355
+ for (const [binaryKey, binaryData] of Object.entries(itemBinary)) {
356
+ const data = binaryData;
357
+ if (data.mimeType && data.mimeType.startsWith('image/')) {
358
+ const base64Data = data.data;
359
+ if (base64Data) {
360
+ enhancedDoc.base64Image = `data:${data.mimeType};base64,${base64Data}`;
361
+ enhancedDoc.metadata._binaryKey = binaryKey;
362
+ this.logger.debug(`Extracted image from binary '${binaryKey}' (${data.mimeType}) for item ${i} (expression source)`);
363
+ break;
364
+ }
365
+ }
366
+ }
367
+ }
368
+ documents.push(enhancedDoc);
369
+ });
318
370
  }
319
371
  }
320
372
  if (documents.length === 0) {
@@ -338,32 +390,65 @@ class VLMComplexityWorkflow {
338
390
  // Return each document as a separate item
339
391
  return [
340
392
  classifiedDocs.map((doc) => {
341
- const outputItem = { json: doc };
393
+ // Flatten structure for better n8n usability
394
+ const flattenedJson = {
395
+ // Classification results (top level for visibility)
396
+ complexityClass: doc._complexityClass,
397
+ complexityConfidence: doc._complexityConfidence,
398
+ processingTime: doc._processingTime,
399
+ modelUsed: doc._modelUsed,
400
+ // Document content
401
+ content: doc.pageContent,
402
+ // Original metadata (if any)
403
+ ...(doc.metadata && doc.metadata._itemIndex !== undefined ? { itemIndex: doc.metadata._itemIndex } : {}),
404
+ ...(doc._originalIndex !== undefined ? { originalIndex: doc._originalIndex } : {}),
405
+ };
406
+ const outputItem = { json: flattenedJson };
342
407
  // Restore original binary data if it was preserved
343
408
  if (doc.metadata && doc.metadata._originalBinary) {
344
409
  outputItem.binary = doc.metadata._originalBinary;
345
- // Clean up internal metadata from output JSON
346
- delete doc.metadata._originalBinary;
347
- delete doc.metadata._binaryKey;
348
410
  }
349
411
  return outputItem;
350
412
  }),
351
413
  ];
352
414
  }
353
415
  else if (outputFormat === 'original') {
354
- // Maintain original structure but add classifications
355
- const outputItems = items.map((item) => ({
356
- json: {
416
+ // Maintain original structure but add flattened classification metadata
417
+ const outputItems = items.map((item, index) => {
418
+ // Find classification for this item
419
+ const itemClassification = classifiedDocs.find((doc) => { var _a; return ((_a = doc.metadata) === null || _a === void 0 ? void 0 : _a._itemIndex) === index || doc._originalIndex === index; });
420
+ const enhancedJson = {
357
421
  ...item.json,
358
- _classifications: classifiedDocs,
359
- },
360
- binary: item.binary, // Preserve original binaries
361
- }));
422
+ };
423
+ // Add classification metadata at top level
424
+ if (itemClassification) {
425
+ enhancedJson.complexityClass = itemClassification._complexityClass;
426
+ enhancedJson.complexityConfidence = itemClassification._complexityConfidence;
427
+ enhancedJson.processingTime = itemClassification._processingTime;
428
+ enhancedJson.modelUsed = itemClassification._modelUsed;
429
+ }
430
+ return {
431
+ json: enhancedJson,
432
+ binary: item.binary, // Preserve original binaries
433
+ };
434
+ });
362
435
  return [outputItems];
363
436
  }
364
437
  else {
365
- // Default: return documents array
366
- return [[{ json: { documents: classifiedDocs } }]];
438
+ // Default: return documents array with flattened structure
439
+ const flattenedDocs = classifiedDocs.map((doc) => {
440
+ var _a;
441
+ return ({
442
+ complexityClass: doc._complexityClass,
443
+ complexityConfidence: doc._complexityConfidence,
444
+ processingTime: doc._processingTime,
445
+ modelUsed: doc._modelUsed,
446
+ content: doc.pageContent,
447
+ itemIndex: (_a = doc.metadata) === null || _a === void 0 ? void 0 : _a._itemIndex,
448
+ originalIndex: doc._originalIndex,
449
+ });
450
+ });
451
+ return [[{ json: { documents: flattenedDocs } }]];
367
452
  }
368
453
  }
369
454
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-vlm",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "Vision-Language Models for n8n - Lightweight specialized VLMs for document analysis and classification",
5
5
  "main": "index.js",
6
6
  "author": "Gabriel BRUMENT",