Files
dj/integration-work/test-local-adapter.cjs

199 lines
9.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// ../huobao-source/backend/src/services/adapters/local-video.ts
var local_video_exports = {};
__export(local_video_exports, {
LocalVideoAdapter: () => LocalVideoAdapter
});
module.exports = __toCommonJS(local_video_exports);
// ../huobao-source/backend/src/services/adapters/url.ts
function joinProviderUrl(baseUrl, requiredPrefix, path) {
const normalizedBase = (baseUrl || "").replace(/\/+$/, "");
const normalizedPrefix = normalizeSegment(requiredPrefix);
const normalizedPath = normalizeSegment(path);
if (!normalizedBase) {
return `${normalizedPrefix}${normalizedPath}`;
}
try {
const url = new URL(normalizedBase);
const currentPath = url.pathname.replace(/\/+$/, "");
const mergedPrefix = currentPath.endsWith(normalizedPrefix) ? currentPath : `${currentPath}${normalizedPrefix}`;
url.pathname = `${mergedPrefix}${normalizedPath}`.replace(/\/{2,}/g, "/");
return url.toString();
} catch {
const basePath = normalizedBase.endsWith(normalizedPrefix) ? normalizedBase : `${normalizedBase}${normalizedPrefix}`;
return `${basePath}${normalizedPath}`;
}
}
function normalizeSegment(segment) {
if (!segment) return "";
return segment.startsWith("/") ? segment : `/${segment}`;
}
// ../huobao-source/backend/src/services/adapters/minimax-video.ts
var H3_MODEL_PREFIX = "minimax-h3";
var DEFAULT_MODEL = "MiniMax-H3";
var REF_LIMITS = { images: 9, videos: 3, audios: 3, total: 12 };
var PROMPT_MAX_CHARS = 7e3;
var VALID_RATIOS = /* @__PURE__ */ new Set(["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"]);
function parseUrlArray(raw) {
if (!raw) return [];
try {
const arr = JSON.parse(raw);
return Array.isArray(arr) ? arr.filter((u) => typeof u === "string" && u.trim()) : [];
} catch {
return [];
}
}
var MiniMaxVideoAdapter = class {
provider = "minimax";
buildGenerateRequest(config, record) {
const model = record.model || config.model || DEFAULT_MODEL;
if (!model.toLowerCase().startsWith(H3_MODEL_PREFIX)) {
throw new Error(`\u4EC5\u652F\u6301 MiniMax H3 \u7CFB\u5217\u6A21\u578B\uFF08MiniMax-H3*\uFF09\uFF0C\u5F53\u524D: ${model}`);
}
const prompt = (record.prompt || "").trim();
const refImages = parseUrlArray(record.referenceImageUrls);
const refVideos = parseUrlArray(record.referenceVideoUrls);
const refAudios = parseUrlArray(record.referenceAudioUrls);
const firstFrame = (record.firstFrameUrl || record.imageUrl || "").trim();
const lastFrame = (record.lastFrameUrl || "").trim();
if (!prompt) throw new Error("MiniMax H3 \u8981\u6C42\u5FC5\u987B\u63D0\u4F9B\u63D0\u793A\u8BCD\uFF08text content\uFF09");
if (prompt.length > PROMPT_MAX_CHARS) {
throw new Error(`\u63D0\u793A\u8BCD\u8D85\u957F\uFF1AMiniMax H3 \u4E0A\u9650 ${PROMPT_MAX_CHARS} \u5B57\u7B26\uFF0C\u5F53\u524D ${prompt.length}`);
}
const totalRefs = refImages.length + refVideos.length + refAudios.length + (firstFrame ? 1 : 0) + (lastFrame ? 1 : 0);
if (refImages.length > REF_LIMITS.images || refVideos.length > REF_LIMITS.videos || refAudios.length > REF_LIMITS.audios || totalRefs > REF_LIMITS.total) {
throw new Error(`\u53C2\u8003\u7D20\u6750\u8D85\u9650\uFF1A\u56FE\u7247\u2264${REF_LIMITS.images}\u3001\u89C6\u9891\u2264${REF_LIMITS.videos}\u3001\u97F3\u9891\u2264${REF_LIMITS.audios}\u3001\u603B\u6570\u2264${REF_LIMITS.total}`);
}
const content = [{ type: "text", text: prompt }];
if (firstFrame) content.push({ type: "image_url", image_url: { url: firstFrame }, role: "first_frame" });
if (lastFrame) content.push({ type: "image_url", image_url: { url: lastFrame }, role: "last_frame" });
for (const url of refImages) {
content.push({ type: "image_url", image_url: { url }, role: "reference_image" });
}
for (const url of refVideos) {
content.push({ type: "video_url", video_url: { url }, role: "reference_video" });
}
for (const url of refAudios) {
content.push({ type: "audio_url", audio_url: { url }, role: "reference_audio" });
}
const body = {
model,
content,
duration: this.normalizeDuration(record.duration),
resolution: this.normalizeResolution(record.resolution)
};
if (config.gpu && config.gpu !== "auto") body.gpu = config.gpu;
if (!firstFrame) {
const ratio = (record.aspectRatio || "").trim();
body.ratio = VALID_RATIOS.has(ratio) ? ratio : "16:9";
}
return {
url: joinProviderUrl(config.baseUrl, "/v2", "/video_generation"),
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${config.apiKey}`
},
body
};
}
parseGenerateResponse(result) {
const taskId = result.task_id ?? result.task?.id;
const state = result.task?.status ?? result.status;
const videoUrl = result.task?.content?.url || result.content?.url || result.video_url;
if (videoUrl && (!state || state === "succeeded")) {
return { isAsync: false, videoUrl, taskId: taskId == null ? void 0 : String(taskId), duration: result.task?.duration ?? result.duration };
}
if (taskId != null) return { isAsync: true, taskId: String(taskId) };
throw new Error("No task_id or video url in response");
}
buildPollRequest(config, taskId) {
return {
url: joinProviderUrl(config.baseUrl, "/v2", `/query/video_generation/${taskId}`),
method: "GET",
headers: {
"Authorization": `Bearer ${config.apiKey}`
},
body: void 0
};
}
parsePollResponse(result) {
const task = result.task && typeof result.task === "object" ? result.task : result;
const status = task.status;
if (status === "succeeded") {
return {
status: "completed",
videoUrl: task.content?.url || task.video_url,
duration: task.duration
};
}
if (status === "failed" || status === "cancelled") {
const err = task.error;
const msg = typeof err === "string" ? err : err?.message || JSON.stringify(err) || "Video generation failed";
const code = err && typeof err === "object" && err.code ? `[${err.code}] ` : "";
return { status: "failed", error: `${code}${msg}` };
}
return { status: "processing", stage: task.delivery?.status === "transferring" ? "transferring" : void 0 };
}
extractVideoUrl(result) {
const task = result.task && typeof result.task === "object" ? result.task : result;
return task.content?.url || task.video_url || null;
}
normalizeDuration(duration) {
const parsed = Math.round(Number(duration || 5));
if (!Number.isFinite(parsed)) return 5;
return Math.min(15, Math.max(4, parsed));
}
/** MiniMax 仅 768P / 2K 两档;项目侧 480p/720p 统一归到 768P,1080p/2K 归到 2K */
normalizeResolution(resolution) {
const r = (resolution || "").toLowerCase();
if (r === "2k" || r === "1080p") return "2K";
return "768P";
}
};
// ../huobao-source/backend/src/services/adapters/local-video.ts
var MODELS = /* @__PURE__ */ new Set(["MiniMax-H3", "MiniMax-H3-Hybrid", "MiniMax-H3-R2V-4Step", "LTX-2.3", "LTX-2.3-Text-Preserve", "Wan2.2-I2V", "MiniMax-H3-VDN-H3"]);
var LocalVideoAdapter = class extends MiniMaxVideoAdapter {
provider = "localvideo";
buildGenerateRequest(config, record) {
const model = record.model || config.model || "MiniMax-H3";
if (!MODELS.has(model)) throw new Error(`\u672C\u5730\u89C6\u9891\u4EFB\u52A1\u6C60\u4E0D\u652F\u6301\u6A21\u578B\uFF1A${model}`);
if (record.referenceFileUrl || record.referenceLinkUrl) throw new Error("\u672C\u5730\u89C6\u9891\u6682\u4E0D\u652F\u6301 file / link \u53C2\u8003\u7D20\u6750");
const request = super.buildGenerateRequest(config, { ...record, model: "MiniMax-H3" });
const body = request.body;
const resolution = String(record.resolution || "768P").toUpperCase();
if (!["480P", "720P", "768P", "1080P", "2K", "4K"].includes(resolution)) throw new Error("\u4E0D\u652F\u6301\u7684\u672C\u5730\u89C6\u9891\u5206\u8FA8\u7387");
if (resolution === "4K" && model !== "MiniMax-H3-VDN-H3") throw new Error("4K \u9700\u8981 VDN-H3 \u9AD8\u6E05\u5236\u4F5C\u6A21\u578B");
body.model = model;
body.resolution = resolution;
if (config.gpu && config.gpu !== "auto") body.gpu = config.gpu;
if (record.seed != null) body.seed = record.seed;
return request;
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
LocalVideoAdapter
});