UNPKG

@gluneau/n8n-nodes-venice

Version:

Venice.ai integration for n8n

396 lines 15.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VeniceImage = void 0; class VeniceImage { description = { displayName: 'Venice Image Generation', name: 'veniceImageGeneration', icon: 'file:veniceImage.svg', group: ['transform'], version: 1, description: 'Generate and manipulate images with Venice.ai', defaults: { name: 'Venice Image', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'veniceApi', required: true, }, ], subtitle: 'Venice', requestDefaults: { baseURL: 'https://api.venice.ai/api/v1', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, }, properties: [ { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Generate', value: 'generate', description: 'Generate a new image from a text prompt', action: 'Generate a new image from a text prompt', }, { name: 'Upscale', value: 'upscale', description: 'Upscale or enhance an existing image', action: 'Upscale or enhance an existing image', }, ], default: 'generate', }, { displayName: 'Model', name: 'model', type: 'string', default: 'venice-sd35', description: 'The model to use for image generation', displayOptions: { show: { operation: ['generate'], }, }, required: true, }, { displayName: 'Prompt', name: 'prompt', type: 'string', typeOptions: { rows: 4, }, default: '', description: 'A description of what you want to generate', displayOptions: { show: { operation: ['generate'], }, }, required: true, }, { displayName: 'Image', name: 'image', type: 'string', default: '', description: 'Base64-encoded image to upscale or a URL', displayOptions: { show: { operation: ['upscale'], }, }, required: true, }, { displayName: 'Scale', name: 'scale', type: 'number', typeOptions: { minValue: 1, maxValue: 4, }, default: 2, description: 'The scale factor for upscaling (1-4)', displayOptions: { show: { operation: ['upscale'], }, }, }, { displayName: 'Generation Options', name: 'generationOptions', type: 'collection', displayOptions: { show: { operation: ['generate'], }, }, placeholder: 'Add Option', default: {}, options: [ { displayName: 'Width', name: 'width', type: 'number', typeOptions: { minValue: 64, maxValue: 1280, }, default: 1024, description: 'Width of the generated image', }, { displayName: 'Height', name: 'height', type: 'number', typeOptions: { minValue: 64, maxValue: 1280, }, default: 1024, description: 'Height of the generated image', }, { displayName: 'CFG Scale', name: 'cfg_scale', type: 'number', typeOptions: { minValue: 0.1, maxValue: 20, }, default: 7.5, description: 'How strictly the image should adhere to the prompt', }, { displayName: 'Format', name: 'format', type: 'options', options: [ { name: 'JPEG', value: 'jpeg', }, { name: 'PNG', value: 'png', }, { name: 'WebP', value: 'webp', }, ], default: 'webp', description: 'The image format to return', }, { displayName: 'Hide Watermark', name: 'hide_watermark', type: 'boolean', default: false, description: 'Whether to hide the Venice watermark (may not be honored for all content)', }, { displayName: 'Negative Prompt', name: 'negative_prompt', type: 'string', typeOptions: { rows: 3, }, default: '', description: 'Features to exclude from the image', }, { displayName: 'Return Binary', name: 'return_binary', type: 'boolean', default: false, description: 'Whether to return binary image data instead of base64', }, { displayName: 'Safe Mode', name: 'safe_mode', type: 'boolean', default: true, description: 'Whether to blur images classified as having adult content', }, { displayName: 'Seed', name: 'seed', type: 'number', default: 0, description: 'Random seed for generation (0 for random)', }, { displayName: 'Steps', name: 'steps', type: 'number', typeOptions: { minValue: 1, maxValue: 30, }, default: 20, description: 'Number of diffusion steps (higher = more detailed but slower)', }, { displayName: 'Style Preset', name: 'style_preset', type: 'string', default: '', description: 'An image style to apply (e.g., "3D Model", "Analog Film", "Anime")', }, ], }, { displayName: 'Upscale Options', name: 'upscaleOptions', type: 'collection', displayOptions: { show: { operation: ['upscale'], }, }, placeholder: 'Add Option', default: {}, options: [ { displayName: 'Enhance', name: 'enhance', type: 'boolean', default: false, description: 'Whether to enhance the image during upscaling', }, { displayName: 'Enhance Creativity', name: 'enhanceCreativity', type: 'number', typeOptions: { minValue: 0, maxValue: 1, }, default: 0.5, description: 'How creative the AI should be when enhancing (0-1)', }, { displayName: 'Enhance Prompt', name: 'enhancePrompt', type: 'string', default: '', description: 'Style to apply during enhancement (e.g., "gold", "marble")', }, { displayName: 'Replication', name: 'replication', type: 'number', typeOptions: { minValue: 0, maxValue: 1, }, default: 0.35, description: 'How strongly lines and noise in the base image are preserved', }, ], }, ], }; async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const operation = this.getNodeParameter('operation', i); if (operation === 'generate') { const model = this.getNodeParameter('model', i); const prompt = this.getNodeParameter('prompt', i); const options = this.getNodeParameter('generationOptions', i, {}); const body = { model, prompt, }; Object.assign(body, options); const response = await this.helpers.httpRequestWithAuthentication.call(this, 'veniceApi', { method: 'POST', url: '/image/generate', body, json: true, encoding: options.return_binary ? 'arraybuffer' : undefined, returnFullResponse: options.return_binary ? true : undefined, }); if (options.return_binary) { const newItem = { json: {}, binary: {}, }; const contentType = response.headers['content-type']; let fileExtension = 'webp'; if (contentType === 'image/jpeg') fileExtension = 'jpg'; else if (contentType === 'image/png') fileExtension = 'png'; else if (options.format) { if (options.format === 'jpeg') fileExtension = 'jpg'; else if (options.format === 'png') fileExtension = 'png'; else if (options.format === 'webp') fileExtension = 'webp'; } const fileName = `venice_image_${Date.now()}.${fileExtension}`; newItem.binary.data = await this.helpers.prepareBinaryData(response.body, fileName, contentType); newItem.json = { success: true, fileName, fileExtension, contentType, size: response.body.length, }; returnData.push(newItem); } else { returnData.push({ json: response }); } } else if (operation === 'upscale') { const image = this.getNodeParameter('image', i); const scale = this.getNodeParameter('scale', i); const options = this.getNodeParameter('upscaleOptions', i, {}); const body = { image, scale, }; Object.assign(body, options); const response = await this.helpers.httpRequestWithAuthentication.call(this, 'veniceApi', { method: 'POST', url: '/image/upscale', body, json: true, encoding: 'arraybuffer', returnFullResponse: true, }); const newItem = { json: {}, binary: {}, }; const contentType = response.headers['content-type']; let fileExtension = 'png'; if (contentType === 'image/jpeg') fileExtension = 'jpg'; else if (contentType === 'image/webp') fileExtension = 'webp'; const fileName = `venice_upscaled_${Date.now()}.${fileExtension}`; newItem.binary.data = await this.helpers.prepareBinaryData(response.body, fileName, contentType); newItem.json = { success: true, fileName, fileExtension, contentType, size: response.body.length, scale, }; returnData.push(newItem); } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message } }); continue; } throw error; } } return [returnData]; } } exports.VeniceImage = VeniceImage; //# sourceMappingURL=VeniceImage.node.js.map