UNPKG

n8n-nodes-aimlapi

Version:

Custom n8n node for integrating with the AI/ML API platform (AIMLAPI) to interact with LLMs and multimodal AI models such as chat completion endpoints.

309 lines 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractAudioOutputs = extractAudioOutputs; exports.extractVideoOutputs = extractVideoOutputs; exports.resolveGenerationResponse = resolveGenerationResponse; const promises_1 = require("timers/promises"); const request_1 = require("./request"); const SUCCESS_STATUSES = new Set([ 'succeeded', 'success', 'completed', 'done', 'ready', 'finished', ]); const FAILURE_STATUSES = new Set([ 'failed', 'error', 'cancelled', 'canceled', 'timeout', 'timed_out', 'expired', ]); const DEFAULT_POLL_INTERVAL = 2000; const DEFAULT_MAX_ATTEMPTS = 60; function collectObjects(root) { const collected = []; const visited = new Set(); const stack = [root]; while (stack.length > 0) { const value = stack.pop(); if (!value || typeof value !== 'object') { continue; } if (visited.has(value)) { continue; } visited.add(value); if (Array.isArray(value)) { stack.push(...value); continue; } const objectValue = value; collected.push(objectValue); for (const entry of Object.values(objectValue)) { stack.push(entry); } } return collected; } function normalizeStatus(value) { if (typeof value === 'string' && value.trim() !== '') { return value.trim().toLowerCase(); } return undefined; } function extractStatus(payload) { const candidates = collectObjects(payload); for (const candidate of candidates) { const status = normalizeStatus(candidate.status ?? candidate.state ?? candidate.task_status ?? candidate.job_status ?? candidate.stage ?? (candidate.task && typeof candidate.task === 'object' ? candidate.task.status : undefined)); if (status) { return status; } } return undefined; } function extractGenerationId(payload) { const candidates = collectObjects(payload); for (const candidate of candidates) { const ids = [ candidate.generation_id, candidate.generationId, candidate.id, candidate.task_id, candidate.taskId, candidate.job_id, candidate.jobId, ]; for (const id of ids) { if (typeof id === 'string' && id.trim() !== '') { return id; } } } return undefined; } function extractErrorMessage(payload) { const candidates = collectObjects(payload); for (const candidate of candidates) { if (typeof candidate.error === 'string' && candidate.error.trim() !== '') { return candidate.error; } if (candidate.error && typeof candidate.error === 'object') { const errorObject = candidate.error; const message = (typeof errorObject.message === 'string' && errorObject.message) || (typeof errorObject.error === 'string' && errorObject.error); if (message) { return message; } } if (typeof candidate.message === 'string' && candidate.message.trim() !== '') { return candidate.message; } } return undefined; } function isSuccessfulStatus(status) { if (!status) { return false; } return SUCCESS_STATUSES.has(status); } function isFailureStatus(status) { if (!status) { return false; } return FAILURE_STATUSES.has(status); } function pushIfMediaObject(target, candidate) { const url = candidate.url ?? candidate.audio_url ?? candidate.audioUrl ?? candidate.video_url ?? candidate.videoUrl; const base64 = candidate.b64_json ?? candidate.base64 ?? candidate.audio_base64 ?? candidate.audioBase64 ?? candidate.data ?? candidate.bytes; if (typeof url === 'string' || typeof base64 === 'string') { target.push(candidate); } } function extractAudioOutputsFromObject(objectValue, outputs, visited) { if (visited.has(objectValue)) { return; } visited.add(objectValue); if (Array.isArray(objectValue)) { for (const entry of objectValue) { if (entry && typeof entry === 'object') { extractAudioOutputsFromObject(entry, outputs, visited); } } return; } if (objectValue.audio_file && typeof objectValue.audio_file === 'object') { extractAudioOutputsFromObject(objectValue.audio_file, outputs, visited); } if (objectValue.audio_files && Array.isArray(objectValue.audio_files)) { for (const entry of objectValue.audio_files) { if (entry && typeof entry === 'object') { extractAudioOutputsFromObject(entry, outputs, visited); } } } if (objectValue.audio && typeof objectValue.audio === 'object') { extractAudioOutputsFromObject(objectValue.audio, outputs, visited); } if (objectValue.tracks && Array.isArray(objectValue.tracks)) { for (const entry of objectValue.tracks) { if (entry && typeof entry === 'object') { extractAudioOutputsFromObject(entry, outputs, visited); } } } if (objectValue.files && Array.isArray(objectValue.files)) { for (const entry of objectValue.files) { if (entry && typeof entry === 'object') { extractAudioOutputsFromObject(entry, outputs, visited); } } } if (typeof objectValue.url === 'string' || typeof objectValue.b64_json === 'string' || typeof objectValue.base64 === 'string') { pushIfMediaObject(outputs, objectValue); } for (const value of Object.values(objectValue)) { if (value && typeof value === 'object') { extractAudioOutputsFromObject(value, outputs, visited); } } } function extractVideoOutputsFromObject(objectValue, outputs, visited) { if (visited.has(objectValue)) { return; } visited.add(objectValue); if (Array.isArray(objectValue)) { for (const entry of objectValue) { if (entry && typeof entry === 'object') { extractVideoOutputsFromObject(entry, outputs, visited); } } return; } if (objectValue.video && typeof objectValue.video === 'object') { extractVideoOutputsFromObject(objectValue.video, outputs, visited); } if (objectValue.videos && Array.isArray(objectValue.videos)) { for (const entry of objectValue.videos) { if (entry && typeof entry === 'object') { extractVideoOutputsFromObject(entry, outputs, visited); } } } if (objectValue.assets && Array.isArray(objectValue.assets)) { for (const entry of objectValue.assets) { if (entry && typeof entry === 'object') { extractVideoOutputsFromObject(entry, outputs, visited); } } } if (objectValue.output && typeof objectValue.output === 'object') { extractVideoOutputsFromObject(objectValue.output, outputs, visited); } if (typeof objectValue.url === 'string') { pushIfMediaObject(outputs, objectValue); } for (const value of Object.values(objectValue)) { if (value && typeof value === 'object') { extractVideoOutputsFromObject(value, outputs, visited); } } } function extractAudioOutputs(payload) { const outputs = []; const visited = new Set(); if (payload && typeof payload === 'object') { extractAudioOutputsFromObject(payload, outputs, visited); } return outputs; } function extractVideoOutputs(payload) { const outputs = []; const visited = new Set(); if (payload && typeof payload === 'object') { extractVideoOutputsFromObject(payload, outputs, visited); } return outputs; } function hasMediaPayload(payload, mediaType) { if (mediaType === 'audio') { return extractAudioOutputs(payload).length > 0; } return extractVideoOutputs(payload).length > 0; } function assertNotFailed(payload) { const status = extractStatus(payload); if (isFailureStatus(status)) { const reason = extractErrorMessage(payload); const suffix = reason ? `: ${reason}` : ''; throw new Error(`Generation failed with status "${status}"${suffix}`); } } function shouldPoll(payload, mediaType) { const generationId = extractGenerationId(payload); if (!generationId) { return { poll: false }; } const status = extractStatus(payload); const hasMedia = hasMediaPayload(payload, mediaType); assertNotFailed(payload); if (isSuccessfulStatus(status) && hasMedia) { return { poll: false, generationId }; } if (!status && hasMedia) { return { poll: false, generationId }; } return { poll: true, generationId }; } async function pollForGeneration(context, baseURL, path, generationId, options) { const pollInterval = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL; const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS; let latest; for (let attempt = 0; attempt < maxAttempts; attempt++) { if (attempt > 0) { await (0, promises_1.setTimeout)(pollInterval); } const requestOptions = (0, request_1.createRequestOptions)(baseURL, path, 'GET', { qs: { generation_id: generationId }, }); latest = await context.helpers.httpRequestWithAuthentication.call(context, 'aimlApi', requestOptions); assertNotFailed(latest); const pollState = shouldPoll(latest, options.mediaType); if (!pollState.poll) { return latest; } } throw new Error(`Timed out while waiting for generation to complete (generation_id: ${generationId})`); } async function resolveGenerationResponse(context, baseURL, path, initial, options) { const pollState = shouldPoll(initial, options.mediaType); if (!pollState.poll || !pollState.generationId) { return initial; } return pollForGeneration(context, baseURL, path, pollState.generationId, options); } //# sourceMappingURL=generation.js.map