@n8n/n8n-nodes-langchain
Version:

202 lines • 6.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.description = void 0;
exports.execute = execute;
const n8n_workflow_1 = require("n8n-workflow");
const transport_1 = require("../../../transport");
const descriptions_1 = require("../descriptions");
const properties = [
{
...(0, descriptions_1.modelRLC)('imageModelSearch'),
displayOptions: { show: { '@version': [{ _cnd: { gte: 1.4 } }] } },
},
{
displayName: 'Text Input',
name: 'text',
type: 'string',
placeholder: "e.g. What's in this image?",
default: "What's in this image?",
typeOptions: {
rows: 2,
},
},
{
displayName: 'Input Type',
name: 'inputType',
type: 'options',
default: 'url',
options: [
{
name: 'Image URL(s)',
value: 'url',
},
{
name: 'Binary File(s)',
value: 'base64',
},
],
},
{
displayName: 'URL(s)',
name: 'imageUrls',
type: 'string',
placeholder: 'e.g. https://example.com/image.jpeg',
description: 'URL(s) of the image(s) to analyze, multiple URLs can be added separated by comma',
default: '',
displayOptions: {
show: {
inputType: ['url'],
},
},
},
{
displayName: 'Input Data Field Name',
name: 'binaryPropertyName',
type: 'string',
default: 'data',
placeholder: 'e.g. data',
hint: 'The name of the input field containing the binary file data to be processed',
description: 'Name of the binary property which contains the image(s)',
displayOptions: {
show: {
inputType: ['base64'],
},
},
},
{
displayName: 'Simplify Output',
name: 'simplify',
type: 'boolean',
default: true,
description: 'Whether to simplify the response or not',
},
{
displayName: 'Options',
name: 'options',
placeholder: 'Add Option',
type: 'collection',
default: {},
options: [
{
displayName: 'Detail',
name: 'detail',
type: 'options',
default: 'auto',
options: [
{
name: 'Auto',
value: 'auto',
description: 'Model will look at the image input size and decide if it should use the low or high setting',
},
{
name: 'Low',
value: 'low',
description: 'Return faster responses and consume fewer tokens',
},
{
name: 'High',
value: 'high',
description: 'Return more detailed responses, consumes more tokens',
},
],
},
{
displayName: 'Length of Description (Max Tokens)',
description: 'Fewer tokens will result in shorter, less detailed image description',
name: 'maxTokens',
type: 'number',
default: 300,
typeOptions: {
minValue: 1,
},
},
],
},
];
const displayOptions = {
show: {
operation: ['analyze'],
resource: ['image'],
},
};
exports.description = (0, n8n_workflow_1.updateDisplayOptions)(displayOptions, properties);
async function execute(i) {
let model = 'gpt-4-vision-preview';
if (this.getNode().typeVersion >= 1.4) {
model = this.getNodeParameter('modelId', i, 'gpt-4o', { extractValue: true });
}
const text = this.getNodeParameter('text', i, '');
const inputType = this.getNodeParameter('inputType', i);
const options = this.getNodeParameter('options', i, {});
const content = [
{
type: 'text',
text,
},
];
const detail = options.detail || 'auto';
if (inputType === 'url') {
const imageUrls = this.getNodeParameter('imageUrls', i)
.split(',')
.map((url) => url.trim());
for (const url of imageUrls) {
content.push({
type: 'image_url',
image_url: {
url,
detail,
},
});
}
}
else {
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i)
.split(',')
.map((propertyName) => propertyName.trim());
for (const propertyName of binaryPropertyName) {
const binaryData = this.helpers.assertBinaryData(i, propertyName);
let fileBase64;
if (binaryData.id) {
const chunkSize = 256 * 1024;
const stream = await this.helpers.getBinaryStream(binaryData.id, chunkSize);
const buffer = await this.helpers.binaryToBuffer(stream);
fileBase64 = buffer.toString('base64');
}
else {
fileBase64 = binaryData.data;
}
if (!binaryData) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No binary data exists on item!');
}
content.push({
type: 'image_url',
image_url: {
url: `data:${binaryData.mimeType};base64,${fileBase64}`,
detail,
},
});
}
}
const body = {
model,
messages: [
{
role: 'user',
content,
},
],
max_tokens: options.maxTokens || 300,
};
let response = await transport_1.apiRequest.call(this, 'POST', '/chat/completions', { body });
const simplify = this.getNodeParameter('simplify', i);
if (simplify && response.choices) {
response = { content: response.choices[0].message.content };
}
return [
{
json: response,
pairedItem: { item: i },
},
];
}
//# sourceMappingURL=analyze.operation.js.map