UNPKG

@n8n/n8n-nodes-langchain

Version:

![Banner image](https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png)

183 lines 6.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.description = void 0; exports.execute = execute; const n8n_workflow_1 = require("n8n-workflow"); const utils_1 = require("../../helpers/utils"); const transport_1 = require("../../transport"); const descriptions_1 = require("../descriptions"); function isImagesParameter(param) { if (typeof param !== 'object' || param === null) { return false; } const paramObj = param; if (!('values' in paramObj)) { return true; } if (!Array.isArray(paramObj.values)) { return false; } return paramObj.values.every((item) => { if (typeof item !== 'object' || item === null) { return false; } const itemObj = item; if (!('binaryPropertyName' in itemObj)) { return true; } return (typeof itemObj.binaryPropertyName === 'string' || itemObj.binaryPropertyName === undefined); }); } function isGenerateContentResponse(response) { if (typeof response !== 'object' || response === null) { return false; } const responseObj = response; if (!('candidates' in responseObj) || !Array.isArray(responseObj.candidates)) { return false; } return responseObj.candidates.every((candidate) => { if (typeof candidate !== 'object' || candidate === null) { return false; } const candidateObj = candidate; if (!('content' in candidateObj) || typeof candidateObj.content !== 'object' || candidateObj.content === null) { return false; } const contentObj = candidateObj.content; return 'parts' in contentObj && Array.isArray(contentObj.parts); }); } const properties = [ (0, descriptions_1.modelRLC)('imageEditModelSearch'), { displayName: 'Prompt', name: 'prompt', type: 'string', placeholder: 'e.g. combine the first image with the second image', description: 'Instruction describing how to edit the image', default: '', typeOptions: { rows: 2, }, }, { displayName: 'Images', name: 'images', type: 'fixedCollection', placeholder: 'Add Image', typeOptions: { multipleValues: true, multipleValueButtonText: 'Add Image', }, default: { values: [{ binaryPropertyName: 'data' }] }, description: 'Add one or more binary fields to include images with your prompt', options: [ { displayName: 'Image', name: 'values', values: [ { displayName: 'Binary Field Name', name: 'binaryPropertyName', type: 'string', default: 'data', placeholder: 'e.g. data', description: 'The name of the binary field containing the image data', }, ], }, ], }, { displayName: 'Options', name: 'options', placeholder: 'Add Option', type: 'collection', default: {}, options: [ { displayName: 'Put Output in Field', name: 'binaryPropertyOutput', type: 'string', default: 'edited', hint: 'The name of the output field to put the binary file data in', }, ], }, ]; const displayOptions = { show: { operation: ['edit'], resource: ['image'], }, }; exports.description = (0, n8n_workflow_1.updateDisplayOptions)(displayOptions, properties); async function execute(i) { const prompt = this.getNodeParameter('prompt', i, ''); let model = this.getNodeParameter('modelId', i, '', { extractValue: true }); if (!model) { model = 'models/gemini-2.5-flash-image-preview'; } const binaryPropertyOutput = this.getNodeParameter('options.binaryPropertyOutput', i, 'edited'); const outputKey = typeof binaryPropertyOutput === 'string' ? binaryPropertyOutput : 'data'; const imagesParam = this.getNodeParameter('images', i, { values: [{ binaryPropertyName: 'data' }], }); if (!isImagesParameter(imagesParam)) { throw new Error('Invalid images parameter format'); } const imagesUi = imagesParam.values ?? []; const imageFieldNames = imagesUi .map((v) => v.binaryPropertyName) .filter((n) => Boolean(n)); const fileParts = []; for (const fieldName of imageFieldNames) { const bin = this.helpers.assertBinaryData(i, fieldName); const buf = await this.helpers.getBinaryDataBuffer(i, fieldName); const uploaded = await utils_1.uploadFile.call(this, buf, bin.mimeType); fileParts.push({ fileData: { fileUri: uploaded.fileUri, mimeType: uploaded.mimeType } }); } const generationConfig = { responseModalities: ['IMAGE'], }; const body = { contents: [ { role: 'user', parts: [...fileParts, { text: prompt }], }, ], generationConfig, }; const response = await transport_1.apiRequest.call(this, 'POST', `/v1beta/${model}:generateContent`, { body, }); if (!isGenerateContentResponse(response)) { throw new Error('Invalid response format from Gemini API'); } const promises = response.candidates.map(async (candidate) => { const imagePart = candidate.content.parts.find((part) => 'inlineData' in part); if (!imagePart?.inlineData?.data) { throw new Error('No image data returned from Gemini API'); } const mimeType = imagePart.inlineData.mimeType; const fileName = (0, utils_1.getFilenameFromMimeType)(mimeType, 'image', 'png'); const bufferOut = Buffer.from(imagePart.inlineData.data, 'base64'); const binaryOut = await this.helpers.prepareBinaryData(bufferOut, fileName, mimeType); return { binary: { [outputKey]: binaryOut, }, json: { ...binaryOut, data: undefined, }, pairedItem: { item: i }, }; }); return await Promise.all(promises); } //# sourceMappingURL=edit.operation.js.map