n8n-nodes-vlm 3.1.2 → 3.2.1
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.
|
@@ -91,6 +91,25 @@ class VLMComplexityWorkflow {
|
|
|
91
91
|
placeholder: 'Add Option',
|
|
92
92
|
default: {},
|
|
93
93
|
options: [
|
|
94
|
+
{
|
|
95
|
+
displayName: 'Image Source',
|
|
96
|
+
name: 'imageSource',
|
|
97
|
+
type: 'options',
|
|
98
|
+
options: [
|
|
99
|
+
{
|
|
100
|
+
name: 'From Binary',
|
|
101
|
+
value: 'binary',
|
|
102
|
+
description: 'Extract image from binary field (n8n standard)',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'From Base64 Field',
|
|
106
|
+
value: 'base64field',
|
|
107
|
+
description: 'Use base64 string from JSON field (with or without Data URI prefix)',
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
default: 'binary',
|
|
111
|
+
description: 'Where to get the image data from',
|
|
112
|
+
},
|
|
94
113
|
{
|
|
95
114
|
displayName: 'Binary Field',
|
|
96
115
|
name: 'binaryField',
|
|
@@ -99,13 +118,40 @@ class VLMComplexityWorkflow {
|
|
|
99
118
|
placeholder: 'e.g. data (auto-detect if empty)',
|
|
100
119
|
description: 'Name of the binary field to use for classification. Leave empty to auto-detect first image.',
|
|
101
120
|
},
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Base64 Field',
|
|
123
|
+
name: 'base64Field',
|
|
124
|
+
type: 'string',
|
|
125
|
+
default: 'data',
|
|
126
|
+
placeholder: 'e.g. data, base64Image',
|
|
127
|
+
description: 'JSON field containing base64 string (auto-detects Data URI prefix)',
|
|
128
|
+
},
|
|
102
129
|
{
|
|
103
130
|
displayName: 'Output Base64 Field',
|
|
104
131
|
name: 'outputBase64Field',
|
|
105
132
|
type: 'string',
|
|
106
133
|
default: '',
|
|
107
134
|
placeholder: 'e.g. base64Image',
|
|
108
|
-
description: 'If set, the base64 image
|
|
135
|
+
description: 'If set, the base64 image will be added to output JSON under this field name.',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
displayName: 'Output Base64 Format',
|
|
139
|
+
name: 'outputBase64Format',
|
|
140
|
+
type: 'options',
|
|
141
|
+
options: [
|
|
142
|
+
{
|
|
143
|
+
name: 'Raw Base64',
|
|
144
|
+
value: 'raw',
|
|
145
|
+
description: 'iVBORw0KGgo... (like n8n native)',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'Data URI',
|
|
149
|
+
value: 'datauri',
|
|
150
|
+
description: 'data:image/png;base64,iVBORw0KGgo...',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
default: 'raw',
|
|
154
|
+
description: 'Format of the base64 output (only applies if Output Base64 Field is set)',
|
|
109
155
|
},
|
|
110
156
|
{
|
|
111
157
|
displayName: 'Request Timeout (ms)',
|
|
@@ -140,8 +186,14 @@ class VLMComplexityWorkflow {
|
|
|
140
186
|
const model = this.getNodeParameter('model', 0);
|
|
141
187
|
const options = this.getNodeParameter('options', 0, {});
|
|
142
188
|
const timeout = (_a = options.timeout) !== null && _a !== void 0 ? _a : 30000;
|
|
189
|
+
const imageSource = options.imageSource || 'binary';
|
|
143
190
|
const binaryField = options.binaryField || '';
|
|
191
|
+
const base64Field = options.base64Field || 'data';
|
|
144
192
|
const outputBase64Field = options.outputBase64Field || '';
|
|
193
|
+
const outputBase64Format = options.outputBase64Format || 'raw';
|
|
194
|
+
// DEBUG: Log options to diagnose format bug
|
|
195
|
+
this.logger.debug(`VLM DEBUG OPTIONS: imageSource='${imageSource}', outputBase64Format='${outputBase64Format}', outputBase64Field='${outputBase64Field}'`);
|
|
196
|
+
this.logger.debug(`VLM DEBUG: outputBase64Format === 'raw' ? ${outputBase64Format === 'raw'}`);
|
|
145
197
|
// Verify server has classifier capability (optional check)
|
|
146
198
|
const status = await (0, vlm_logic_1.checkServerStatus)(this, serverUrl, timeout);
|
|
147
199
|
if (status.status === 'error') {
|
|
@@ -156,31 +208,59 @@ class VLMComplexityWorkflow {
|
|
|
156
208
|
// Process each input item
|
|
157
209
|
for (let i = 0; i < items.length; i++) {
|
|
158
210
|
const item = items[i];
|
|
159
|
-
// Extract base64 image
|
|
160
|
-
let base64Image;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
211
|
+
// Extract base64 image - track both raw and Data URI formats
|
|
212
|
+
let base64Image; // Data URI format for API
|
|
213
|
+
let rawBase64; // Raw base64 without prefix
|
|
214
|
+
let mimeType = 'image/png';
|
|
215
|
+
if (imageSource === 'base64field') {
|
|
216
|
+
// Extract from JSON field
|
|
217
|
+
const fieldValue = item.json[base64Field];
|
|
218
|
+
if (fieldValue) {
|
|
219
|
+
// Auto-detect if it's already a Data URI
|
|
220
|
+
const dataUriMatch = fieldValue.match(/^data:([^;]+);base64,(.+)$/);
|
|
221
|
+
if (dataUriMatch) {
|
|
222
|
+
mimeType = dataUriMatch[1];
|
|
223
|
+
rawBase64 = dataUriMatch[2];
|
|
224
|
+
base64Image = fieldValue; // Already in Data URI format
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
// Raw base64, wrap in Data URI
|
|
228
|
+
rawBase64 = fieldValue;
|
|
229
|
+
base64Image = `data:${mimeType};base64,${rawBase64}`;
|
|
168
230
|
}
|
|
231
|
+
this.logger.debug(`Item ${i}: Using base64 from JSON field '${base64Field}' (${mimeType})`);
|
|
169
232
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Extract from binary (default)
|
|
236
|
+
if (item.binary) {
|
|
237
|
+
if (binaryField && item.binary[binaryField]) {
|
|
238
|
+
// Use specified binary field
|
|
239
|
+
const data = item.binary[binaryField];
|
|
240
|
+
if (data.data) {
|
|
241
|
+
mimeType = data.mimeType || 'image/png';
|
|
242
|
+
rawBase64 = data.data;
|
|
243
|
+
base64Image = `data:${mimeType};base64,${rawBase64}`;
|
|
244
|
+
this.logger.debug(`Item ${i}: Using specified binary field '${binaryField}' (${mimeType})`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Auto-detect first image (default behavior)
|
|
249
|
+
for (const [binaryKey, binaryData] of Object.entries(item.binary)) {
|
|
250
|
+
const data = binaryData;
|
|
251
|
+
if (data.mimeType && data.mimeType.startsWith('image/') && data.data) {
|
|
252
|
+
mimeType = data.mimeType;
|
|
253
|
+
rawBase64 = data.data;
|
|
254
|
+
base64Image = `data:${mimeType};base64,${rawBase64}`;
|
|
255
|
+
this.logger.debug(`Item ${i}: Auto-detected image from binary '${binaryKey}' (${mimeType})`);
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
178
258
|
}
|
|
179
259
|
}
|
|
180
260
|
}
|
|
181
261
|
}
|
|
182
262
|
if (!base64Image) {
|
|
183
|
-
this.logger.warn(`Item ${i}: No image found
|
|
263
|
+
this.logger.warn(`Item ${i}: No image found (source: ${imageSource})`);
|
|
184
264
|
}
|
|
185
265
|
// Classify the document
|
|
186
266
|
const classification = await (0, vlm_logic_1.classifySingleDocument)(this, {
|
|
@@ -189,6 +269,13 @@ class VLMComplexityWorkflow {
|
|
|
189
269
|
timeout,
|
|
190
270
|
});
|
|
191
271
|
this.logger.debug(`Item ${i}: Classified as ${classification.complexity} (confidence: ${classification.confidence})`);
|
|
272
|
+
// Determine base64 output value based on format preference
|
|
273
|
+
// DEBUG: Log values before output decision
|
|
274
|
+
this.logger.debug(`VLM DEBUG OUTPUT: rawBase64 defined=${!!rawBase64}, rawBase64 prefix='${rawBase64 === null || rawBase64 === void 0 ? void 0 : rawBase64.substring(0, 25)}...'`);
|
|
275
|
+
this.logger.debug(`VLM DEBUG OUTPUT: base64Image prefix='${base64Image === null || base64Image === void 0 ? void 0 : base64Image.substring(0, 35)}...'`);
|
|
276
|
+
this.logger.debug(`VLM DEBUG OUTPUT: choosing ${outputBase64Format === 'raw' ? 'rawBase64' : 'base64Image'}`);
|
|
277
|
+
const outputBase64Value = outputBase64Format === 'raw' ? rawBase64 : base64Image;
|
|
278
|
+
this.logger.debug(`VLM DEBUG OUTPUT: outputBase64Value prefix='${outputBase64Value === null || outputBase64Value === void 0 ? void 0 : outputBase64Value.substring(0, 35)}...'`);
|
|
192
279
|
// Build output item with BOTH json AND binary
|
|
193
280
|
const outputItem = {
|
|
194
281
|
json: {
|
|
@@ -201,8 +288,8 @@ class VLMComplexityWorkflow {
|
|
|
201
288
|
...item.json,
|
|
202
289
|
// Item tracking
|
|
203
290
|
_itemIndex: i,
|
|
204
|
-
// Optional: include base64 in output JSON
|
|
205
|
-
...(outputBase64Field &&
|
|
291
|
+
// Optional: include base64 in output JSON (format depends on outputBase64Format)
|
|
292
|
+
...(outputBase64Field && outputBase64Value ? { [outputBase64Field]: outputBase64Value } : {}),
|
|
206
293
|
},
|
|
207
294
|
// ALWAYS preserve binary data
|
|
208
295
|
binary: item.binary,
|
package/package.json
CHANGED