n8n-nodes-local-ai-stack
Version:
n8n custom nodes for AI services including image captionning, OCR, face detection, and more AI-powered features
206 lines (205 loc) • 9.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalAIStack = void 0;
class LocalAIStack {
constructor() {
this.description = {
displayName: "Local AI Stack",
name: "localAIStack",
icon: "file:local_ai_stack.jpg",
group: ["transform"],
version: 1,
description: "Local AI Stack services for image processing and analysis",
defaults: {
name: "Local AI Stack",
},
inputs: ["main"],
outputs: ["main"],
properties: [
{
displayName: "🚀 Débloquez des fonctionnalités Premium : Audio Transcription, Vision LLM, Text-to-Speech, traitement d'images/vidéos avancé, Embeddings multimodaux, Vector DB et plus encore. <a href='https://tally.so/r/w76z7A' target='_blank'>Rejoignez la liste d'attente ici</a>",
name: "premiumNotice",
type: "notice",
default: "",
},
{
displayName: "Service",
name: "service",
type: "options",
options: [
{
name: "Extract Text from Image",
value: "ocr",
description: "Extract text from images using OCR",
},
{
name: "Detect Faces from Image",
value: "faces",
description: "Detect and analyze faces in images",
},
{
name: "💎 Audio Transcription (Speech-to-Text)",
value: "audio_transcription",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Visual Question Answering (Vision LLM)",
value: "visual_qa",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Text-to-Speech",
value: "text_to_speech",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Image Utils (Crop, Blur, Upscale...)",
value: "image_utils",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Video Utils (Trim, Edit...)",
value: "video_utils",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Multimodal Embeddings (Text-Image Similarity...)",
value: "multimodal_embeddings",
description: "⚠️ Premium feature - Not available in free tier",
},
{
name: "💎 Vector DB",
value: "vector_db",
description: "⚠️ Premium feature - Not available in free tier",
},
],
default: "ocr",
required: true,
description: "Select the AI service to use",
},
{
displayName: "Image Source",
name: "imageSource",
type: "options",
options: [
{
name: "URL",
value: "url",
},
{
name: "Upload File",
value: "file",
},
],
default: "url",
description: "Choose whether to provide an image URL or upload a file",
},
{
displayName: "Image URL",
name: "imageUrl",
type: "string",
default: "",
placeholder: "https://example.com/image.jpg",
required: true,
description: "URL of the image to send to the AI service",
displayOptions: {
show: {
imageSource: ["url"],
},
},
},
{
displayName: "Image File",
name: "imageFile",
type: "string",
default: "data",
required: true,
description: "The input binary field containing the image file to process",
displayOptions: {
show: {
imageSource: ["file"],
},
},
hint: "The name of the binary property that contains the image data",
},
{
displayName: "Server URL",
name: "serverUrl",
type: "string",
default: "http://localhost:9454",
placeholder: "http://localhost:9454",
required: false,
description: "AI-Hub server URL (optional)",
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
// Liste des services premium
const premiumServices = ["audio_transcription", "visual_qa", "text_to_speech", "image_utils", "video_utils", "multimodal_embeddings", "vector_db"];
for (let i = 0; i < items.length; i++) {
try {
const serverUrl = this.getNodeParameter("serverUrl", i, "http://localhost:9454");
const service = this.getNodeParameter("service", i);
const imageSource = this.getNodeParameter("imageSource", i);
// Vérifier si c'est un service premium
if (premiumServices.includes(service)) {
throw new Error("⚠️ Cette option n'est disponible qu'en version Premium. " +
"Rejoignez notre liste d'attente pour être parmi les premiers à bénéficier de cette fonctionnalité : https://tally.so/r/w76z7A");
}
// Build the complete URL ensuring there are no double slashes
const baseUrl = serverUrl.endsWith("/") ? serverUrl.slice(0, -1) : serverUrl;
const fullUrl = `${baseUrl}/${service}/`;
let response;
if (imageSource === "url") {
// Use image URL
const imageUrl = this.getNodeParameter("imageUrl", i);
response = await this.helpers.request({
method: "POST",
uri: fullUrl,
body: { image_url: imageUrl },
json: true,
});
}
else {
// Use uploaded file
const binaryPropertyName = this.getNodeParameter("imageFile", i);
const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
const buffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
response = await this.helpers.request({
method: "POST",
uri: fullUrl,
formData: {
image_file: {
value: buffer,
options: {
filename: binaryData.fileName || "image.jpg",
contentType: binaryData.mimeType || "image/jpeg",
},
},
},
json: true,
});
}
returnData.push({
json: response,
});
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.LocalAIStack = LocalAIStack;