@neta-art/generation 0.1.17 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -2
- package/dist/{builtins-D7Zojd9j.d.ts → builtins-8R5iZQ10.d.ts} +12 -2
- package/dist/{builtins-D7Zojd9j.d.ts.map → builtins-8R5iZQ10.d.ts.map} +1 -1
- package/dist/{builtins-BqqqQ7Ib.js → builtins-B4Agk9nt.js} +153 -1
- package/dist/builtins-B4Agk9nt.js.map +1 -0
- package/dist/builtins.d.ts +1 -1
- package/dist/builtins.js +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/{export-config-CIZi8HJ8.js → export-config-2OmCf-nP.js} +558 -69
- package/dist/export-config-2OmCf-nP.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/models/higgs-tts.yaml +66 -0
- package/models/qwen-audio-3.0-tts-flash.yaml +44 -0
- package/models/qwen-audio-3.0-tts-plus.yaml +44 -0
- package/models/qwen-tts.yaml +44 -0
- package/package.json +23 -20
- package/dist/builtins-BqqqQ7Ib.js.map +0 -1
- package/dist/export-config-CIZi8HJ8.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as compactArray, c as slugifyFileName, i as cloneJson, l as MODEL_SCHEMA, n as getBuiltinGenerationModel, o as compactObject, r as listBuiltinGenerationModels, s as getBlockMeta, t as builtinGenerationModels } from "./builtins-
|
|
1
|
+
import { a as compactArray, c as slugifyFileName, i as cloneJson, l as MODEL_SCHEMA, n as getBuiltinGenerationModel, o as compactObject, r as listBuiltinGenerationModels, s as getBlockMeta, t as builtinGenerationModels } from "./builtins-B4Agk9nt.js";
|
|
2
2
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { extname, join } from "node:path";
|
|
4
4
|
import { parse, stringify } from "yaml";
|
|
@@ -270,22 +270,22 @@ function mergeTextBlocks(declaration, content) {
|
|
|
270
270
|
|
|
271
271
|
//#endregion
|
|
272
272
|
//#region src/adapters/ark-video-generations.ts
|
|
273
|
-
const REQUEST_TIMEOUT_MS$
|
|
274
|
-
const DEFAULT_POLL_INTERVAL_SEC$
|
|
275
|
-
const DEFAULT_MAX_WAIT_SEC$
|
|
276
|
-
function sleep$
|
|
273
|
+
const REQUEST_TIMEOUT_MS$7 = 186e4;
|
|
274
|
+
const DEFAULT_POLL_INTERVAL_SEC$3 = 2;
|
|
275
|
+
const DEFAULT_MAX_WAIT_SEC$3 = 600;
|
|
276
|
+
function sleep$3(ms) {
|
|
277
277
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
278
278
|
}
|
|
279
|
-
function asString$
|
|
279
|
+
function asString$3(value) {
|
|
280
280
|
return typeof value === "string" && value ? value : void 0;
|
|
281
281
|
}
|
|
282
282
|
function asNumber$1(value) {
|
|
283
283
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
284
284
|
}
|
|
285
|
-
function asBoolean(value) {
|
|
285
|
+
function asBoolean$1(value) {
|
|
286
286
|
return typeof value === "boolean" ? value : void 0;
|
|
287
287
|
}
|
|
288
|
-
function normalizeStatus$
|
|
288
|
+
function normalizeStatus$3(value) {
|
|
289
289
|
const status = value.toLowerCase();
|
|
290
290
|
return status === "success" ? "succeeded" : status;
|
|
291
291
|
}
|
|
@@ -293,7 +293,7 @@ function getIntegerParameter(parameters, key, fallback) {
|
|
|
293
293
|
const value = parameters[key];
|
|
294
294
|
return typeof value === "number" && Number.isInteger(value) ? value : fallback;
|
|
295
295
|
}
|
|
296
|
-
function getMediaRole(block) {
|
|
296
|
+
function getMediaRole$1(block) {
|
|
297
297
|
const role = getBlockMeta(block)?.role;
|
|
298
298
|
return typeof role === "string" && role ? role : void 0;
|
|
299
299
|
}
|
|
@@ -306,7 +306,7 @@ function isReferenceMedia(item) {
|
|
|
306
306
|
function assertSingleRole(media, role, message) {
|
|
307
307
|
if (media.filter((item) => item.role === role).length > 1) throw new GenerationValidationError(message);
|
|
308
308
|
}
|
|
309
|
-
function classifyMedia(media) {
|
|
309
|
+
function classifyMedia$1(media) {
|
|
310
310
|
if (media.length === 0) return null;
|
|
311
311
|
for (const item of media) {
|
|
312
312
|
if (item.kind === "image" && item.role && item.role !== "first_frame" && item.role !== "last_frame" && item.role !== "reference_image") throw new GenerationValidationError("Image input must use meta.role first_frame, last_frame, or reference_image");
|
|
@@ -353,15 +353,15 @@ function buildMetadataContent(media, mode) {
|
|
|
353
353
|
}
|
|
354
354
|
return content;
|
|
355
355
|
}
|
|
356
|
-
async function resolveMedia(input, media) {
|
|
356
|
+
async function resolveMedia$1(input, media) {
|
|
357
357
|
return Promise.all(media.map(async (item) => ({
|
|
358
358
|
kind: item.kind,
|
|
359
359
|
role: item.role,
|
|
360
360
|
url: await input.context.resolveSource(item.source)
|
|
361
361
|
})));
|
|
362
362
|
}
|
|
363
|
-
function extractTaskId$
|
|
364
|
-
const taskId = asString$
|
|
363
|
+
function extractTaskId$3(response) {
|
|
364
|
+
const taskId = asString$3(response.task_id) ?? asString$3(response.id);
|
|
365
365
|
if (!taskId) throw new GenerationProviderError("Video generation provider did not return a task id", { details: { response } });
|
|
366
366
|
return taskId;
|
|
367
367
|
}
|
|
@@ -369,9 +369,9 @@ function normalizeTaskStatus(response) {
|
|
|
369
369
|
if (response.data) {
|
|
370
370
|
const wrapper = response.data;
|
|
371
371
|
const native = wrapper.data;
|
|
372
|
-
const status = normalizeStatus$
|
|
373
|
-
const videoUrl = asString$
|
|
374
|
-
const firstFrameUrl = asString$
|
|
372
|
+
const status = normalizeStatus$3(asString$3(native?.status) ?? asString$3(wrapper.status) ?? "unknown");
|
|
373
|
+
const videoUrl = asString$3(wrapper.result_url) ?? asString$3(native?.content?.video_url);
|
|
374
|
+
const firstFrameUrl = asString$3(wrapper.first_frame) ?? asString$3(native?.content?.first_frame);
|
|
375
375
|
const metadata = {
|
|
376
376
|
progress: wrapper.progress,
|
|
377
377
|
resolution: native?.resolution,
|
|
@@ -398,7 +398,7 @@ function normalizeTaskStatus(response) {
|
|
|
398
398
|
metadata: {}
|
|
399
399
|
};
|
|
400
400
|
}
|
|
401
|
-
async function requestJson$
|
|
401
|
+
async function requestJson$3(input, path, init) {
|
|
402
402
|
const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, path), {
|
|
403
403
|
...init,
|
|
404
404
|
headers: {
|
|
@@ -406,7 +406,7 @@ async function requestJson$2(input, path, init) {
|
|
|
406
406
|
"Content-Type": "application/json",
|
|
407
407
|
...init.headers
|
|
408
408
|
}
|
|
409
|
-
}, REQUEST_TIMEOUT_MS$
|
|
409
|
+
}, REQUEST_TIMEOUT_MS$7);
|
|
410
410
|
if (!response.ok) {
|
|
411
411
|
const body = await response.text().catch(() => response.statusText);
|
|
412
412
|
throw new GenerationProviderError("Video generation provider request failed", {
|
|
@@ -422,20 +422,20 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
422
422
|
const inputMedia = input.request.content.filter((block) => block.type === "image" || block.type === "video").map((block) => ({
|
|
423
423
|
kind: block.type,
|
|
424
424
|
source: block.source,
|
|
425
|
-
role: getMediaRole(block)
|
|
425
|
+
role: getMediaRole$1(block)
|
|
426
426
|
}));
|
|
427
|
-
const mode = classifyMedia(inputMedia);
|
|
428
|
-
const media = await resolveMedia(input, inputMedia);
|
|
429
|
-
const resolution = asString$
|
|
430
|
-
const ratio = asString$
|
|
427
|
+
const mode = classifyMedia$1(inputMedia);
|
|
428
|
+
const media = await resolveMedia$1(input, inputMedia);
|
|
429
|
+
const resolution = asString$3(input.parameters.resolution) ?? "720p";
|
|
430
|
+
const ratio = asString$3(input.request.parameters?.ratio) ?? asString$3(input.parameters.ratio) ?? "16:9";
|
|
431
431
|
const duration = getIntegerParameter(input.parameters, "duration", 5);
|
|
432
432
|
const fps = getIntegerParameter(input.parameters, "fps", 30);
|
|
433
|
-
const pollIntervalSec = getIntegerParameter(input.parameters, "poll_interval", DEFAULT_POLL_INTERVAL_SEC$
|
|
434
|
-
const maxWaitSec = getIntegerParameter(input.parameters, "max_wait", DEFAULT_MAX_WAIT_SEC$
|
|
435
|
-
const generateAudio = asBoolean(input.parameters.generate_audio) ?? true;
|
|
436
|
-
const returnLastFrame = asBoolean(input.parameters.return_last_frame) ?? true;
|
|
437
|
-
const cameraFixed = asBoolean(input.parameters.camera_fixed) ?? false;
|
|
438
|
-
const watermark = asBoolean(input.parameters.watermark) ?? false;
|
|
433
|
+
const pollIntervalSec = getIntegerParameter(input.parameters, "poll_interval", DEFAULT_POLL_INTERVAL_SEC$3);
|
|
434
|
+
const maxWaitSec = getIntegerParameter(input.parameters, "max_wait", DEFAULT_MAX_WAIT_SEC$3);
|
|
435
|
+
const generateAudio = asBoolean$1(input.parameters.generate_audio) ?? true;
|
|
436
|
+
const returnLastFrame = asBoolean$1(input.parameters.return_last_frame) ?? true;
|
|
437
|
+
const cameraFixed = asBoolean$1(input.parameters.camera_fixed) ?? false;
|
|
438
|
+
const watermark = asBoolean$1(input.parameters.watermark) ?? false;
|
|
439
439
|
const seed = asNumber$1(input.parameters.seed);
|
|
440
440
|
const payload = {
|
|
441
441
|
model: input.declaration.model,
|
|
@@ -458,14 +458,14 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
458
458
|
if (firstImage) payload.image = firstImage.url;
|
|
459
459
|
}
|
|
460
460
|
payload.metadata = metadata;
|
|
461
|
-
const taskId = extractTaskId$
|
|
461
|
+
const taskId = extractTaskId$3(await requestJson$3(input, "/v1/video/generations", {
|
|
462
462
|
method: "POST",
|
|
463
463
|
body: JSON.stringify(payload)
|
|
464
464
|
}));
|
|
465
465
|
const startedAt = Date.now();
|
|
466
466
|
while (Date.now() - startedAt <= maxWaitSec * 1e3) {
|
|
467
|
-
await sleep$
|
|
468
|
-
const rawStatus = await requestJson$
|
|
467
|
+
await sleep$3(pollIntervalSec * 1e3);
|
|
468
|
+
const rawStatus = await requestJson$3(input, `/v1/video/generations/${encodeURIComponent(taskId)}`, { method: "GET" });
|
|
469
469
|
const status = normalizeTaskStatus(rawStatus);
|
|
470
470
|
if (status.status === "succeeded") {
|
|
471
471
|
if (!status.videoUrl) throw new GenerationProviderError("Video generation succeeded but returned no video URL", { details: compactObject({
|
|
@@ -510,9 +510,205 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
510
510
|
throw new GenerationTimeoutError("Timed out waiting for video generation", { taskId });
|
|
511
511
|
}
|
|
512
512
|
|
|
513
|
+
//#endregion
|
|
514
|
+
//#region src/adapters/audio-speech.ts
|
|
515
|
+
const REQUEST_TIMEOUT_MS$6 = 21e4;
|
|
516
|
+
const QWEN_MODELS = new Set([
|
|
517
|
+
"qwen-tts",
|
|
518
|
+
"qwen-audio-3.0-tts-plus",
|
|
519
|
+
"qwen-audio-3.0-tts-flash"
|
|
520
|
+
]);
|
|
521
|
+
const QWEN_AUDIO_3_MODELS = new Set(["qwen-audio-3.0-tts-plus", "qwen-audio-3.0-tts-flash"]);
|
|
522
|
+
const HIGGS_MODEL = "higgs-tts";
|
|
523
|
+
function isRecord$5(value) {
|
|
524
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
525
|
+
}
|
|
526
|
+
function textBlocks(input) {
|
|
527
|
+
return input.request.content.filter((block) => block.type === "text");
|
|
528
|
+
}
|
|
529
|
+
function audioBlocks(input) {
|
|
530
|
+
return input.request.content.filter((block) => block.type === "audio");
|
|
531
|
+
}
|
|
532
|
+
function validateMetaKeys(label, meta, allowed) {
|
|
533
|
+
for (const key of Object.keys(meta ?? {})) if (!allowed.has(key)) throw new GenerationValidationError(`Unknown ${label} field: ${key}`);
|
|
534
|
+
}
|
|
535
|
+
function validateHttpUrl(value, label) {
|
|
536
|
+
if (typeof value !== "string") throw new GenerationValidationError(`${label} must be a valid HTTP(S) URL`);
|
|
537
|
+
const trimmed = value.trim();
|
|
538
|
+
if (!trimmed) throw new GenerationValidationError(`${label} must be a non-empty HTTP(S) URL`);
|
|
539
|
+
try {
|
|
540
|
+
const url = new URL(trimmed);
|
|
541
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("unsupported protocol");
|
|
542
|
+
} catch {
|
|
543
|
+
throw new GenerationValidationError(`${label} must be a valid HTTP(S) URL`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function validateCommonContent(input) {
|
|
547
|
+
const texts = textBlocks(input);
|
|
548
|
+
if (texts.length !== 1 || typeof texts[0]?.text !== "string" || !texts[0].text.trim()) throw new GenerationValidationError(`${input.declaration.model} requires exactly one non-empty text content block as input`);
|
|
549
|
+
const audio = audioBlocks(input);
|
|
550
|
+
for (const [index, block] of audio.entries()) {
|
|
551
|
+
if (block.source.type !== "url") throw new GenerationValidationError(`${input.declaration.model} reference audio must use a URL source`);
|
|
552
|
+
validateHttpUrl(block.source.url, `audio content block ${index} URL`);
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
text: texts[0],
|
|
556
|
+
audio
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
function validateQwen(input, text, audio) {
|
|
560
|
+
if (audio.length > 1) throw new GenerationValidationError(`${input.declaration.model} supports at most one reference audio`);
|
|
561
|
+
const requestMetaKeys = new Set(["voice_prompt", "preview_text"]);
|
|
562
|
+
validateMetaKeys("request.metadata", input.request.metadata, requestMetaKeys);
|
|
563
|
+
validateMetaKeys("request.meta", input.request.meta, requestMetaKeys);
|
|
564
|
+
validateMetaKeys("text content meta", text.meta, /* @__PURE__ */ new Set());
|
|
565
|
+
for (const block of audio) validateMetaKeys("audio content meta", block.meta, /* @__PURE__ */ new Set());
|
|
566
|
+
const voicePrompt = input.meta.voice_prompt;
|
|
567
|
+
const hasVoicePrompt = typeof voicePrompt === "string" && voicePrompt.trim().length > 0;
|
|
568
|
+
if (voicePrompt !== void 0 && !hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} meta.voice_prompt must be a non-empty string`);
|
|
569
|
+
if (audio.length === 0 && !hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} requires one reference audio or meta.voice_prompt`);
|
|
570
|
+
if (audio.length > 0 && hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} reference audio and meta.voice_prompt are mutually exclusive`);
|
|
571
|
+
if (QWEN_AUDIO_3_MODELS.has(input.declaration.model) && Array.from(text.text.trim()).length < 15) throw new GenerationValidationError(`${input.declaration.model} requires input of at least 15 Unicode code points`);
|
|
572
|
+
}
|
|
573
|
+
function hasOwnWeight(block) {
|
|
574
|
+
return Object.hasOwn(block.meta ?? {}, "weight");
|
|
575
|
+
}
|
|
576
|
+
function isPositiveFiniteNumber(value) {
|
|
577
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
578
|
+
}
|
|
579
|
+
function validateHiggs(input, text, audio) {
|
|
580
|
+
if (audio.length > 16) throw new GenerationValidationError(`${input.declaration.model} supports at most 16 references`);
|
|
581
|
+
validateMetaKeys("request.metadata", input.request.metadata, /* @__PURE__ */ new Set());
|
|
582
|
+
validateMetaKeys("request.meta", input.request.meta, /* @__PURE__ */ new Set());
|
|
583
|
+
validateMetaKeys("text content meta", text.meta, /* @__PURE__ */ new Set());
|
|
584
|
+
for (const [index, block] of audio.entries()) {
|
|
585
|
+
validateMetaKeys(`audio content block ${index} meta`, block.meta, new Set(["weight"]));
|
|
586
|
+
const weight = block.meta?.weight;
|
|
587
|
+
if (audio.length === 1 && (!hasOwnWeight(block) || weight === void 0)) continue;
|
|
588
|
+
if (!isPositiveFiniteNumber(weight)) throw new GenerationValidationError(`audio content block ${index} meta.weight must be a finite positive number`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function validateAudioSpeechRequest(input) {
|
|
592
|
+
const { text, audio } = validateCommonContent(input);
|
|
593
|
+
if (QWEN_MODELS.has(input.declaration.model)) {
|
|
594
|
+
validateQwen(input, text, audio);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
if (input.declaration.model === HIGGS_MODEL) {
|
|
598
|
+
validateHiggs(input, text, audio);
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
throw new GenerationValidationError(`Unsupported audio speech model: ${input.declaration.model}`);
|
|
602
|
+
}
|
|
603
|
+
function requestIdFromHeaders(headers) {
|
|
604
|
+
return headers.get("x-request-id")?.trim() || headers.get("x-oneapi-request-id")?.trim() || void 0;
|
|
605
|
+
}
|
|
606
|
+
function buildPayload$2(input) {
|
|
607
|
+
const text = textBlocks(input)[0];
|
|
608
|
+
if (!text) throw new GenerationValidationError("Audio speech input was not validated");
|
|
609
|
+
const audio = audioBlocks(input);
|
|
610
|
+
const payload = {
|
|
611
|
+
model: input.declaration.model,
|
|
612
|
+
input: text.text
|
|
613
|
+
};
|
|
614
|
+
if (QWEN_MODELS.has(input.declaration.model)) {
|
|
615
|
+
if (audio[0]?.source.type === "url") payload.ref_audio = audio[0].source.url.trim();
|
|
616
|
+
else payload.metadata = { voice_prompt: input.meta.voice_prompt };
|
|
617
|
+
return payload;
|
|
618
|
+
}
|
|
619
|
+
const firstAudio = audio[0];
|
|
620
|
+
if (audio.length === 1 && firstAudio && (!hasOwnWeight(firstAudio) || firstAudio.meta?.weight === void 0)) {
|
|
621
|
+
if (firstAudio.source.type === "url") payload.ref_audio = firstAudio.source.url.trim();
|
|
622
|
+
return payload;
|
|
623
|
+
}
|
|
624
|
+
if (audio.length > 0) payload.metadata = { references: audio.map((block) => ({
|
|
625
|
+
url: block.source.type === "url" ? block.source.url.trim() : "",
|
|
626
|
+
weight: block.meta?.weight
|
|
627
|
+
})) };
|
|
628
|
+
return payload;
|
|
629
|
+
}
|
|
630
|
+
function parseJson(rawBody) {
|
|
631
|
+
try {
|
|
632
|
+
return JSON.parse(rawBody);
|
|
633
|
+
} catch {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
function nonEmptyString(value) {
|
|
638
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
639
|
+
}
|
|
640
|
+
function providerError(response, rawBody) {
|
|
641
|
+
const requestId = requestIdFromHeaders(response.headers);
|
|
642
|
+
const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
|
|
643
|
+
const parsed = contentType.includes("application/json") || contentType.includes("+json") ? parseJson(rawBody) : void 0;
|
|
644
|
+
const parsedRecord = isRecord$5(parsed) ? parsed : void 0;
|
|
645
|
+
const errorRecord = isRecord$5(parsedRecord?.error) ? parsedRecord.error : void 0;
|
|
646
|
+
const message = nonEmptyString(errorRecord?.message) ?? (rawBody.trim() ? rawBody : void 0) ?? (response.statusText.trim() ? response.statusText : void 0) ?? "Audio speech provider request failed";
|
|
647
|
+
const code = nonEmptyString(errorRecord?.code);
|
|
648
|
+
return new GenerationProviderError(message, {
|
|
649
|
+
status: response.status,
|
|
650
|
+
body: rawBody,
|
|
651
|
+
details: {
|
|
652
|
+
requestId,
|
|
653
|
+
code,
|
|
654
|
+
...parsedRecord ? { error: parsedRecord } : {}
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
function unsupportedSuccessResponse(response, rawBody) {
|
|
659
|
+
const statusText = response.statusText.trim();
|
|
660
|
+
return new GenerationProviderError(response.status === 204 && statusText ? statusText : "Audio speech provider returned an unsupported success response", {
|
|
661
|
+
status: response.status,
|
|
662
|
+
body: rawBody,
|
|
663
|
+
details: { requestId: requestIdFromHeaders(response.headers) }
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
function parseSuccessResponse(response, rawBody) {
|
|
667
|
+
const parsed = parseJson(rawBody);
|
|
668
|
+
if (!isRecord$5(parsed)) throw unsupportedSuccessResponse(response, rawBody);
|
|
669
|
+
const urlValue = nonEmptyString(parsed.url);
|
|
670
|
+
const contentType = nonEmptyString(parsed.content_type);
|
|
671
|
+
if (!urlValue || parsed.media_type !== "audio" || !contentType || !/^audio\/[^\s/;]+(?:\s*;.*)?$/i.test(contentType)) throw unsupportedSuccessResponse(response, rawBody);
|
|
672
|
+
try {
|
|
673
|
+
const url = new URL(urlValue.trim());
|
|
674
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("unsupported protocol");
|
|
675
|
+
} catch {
|
|
676
|
+
throw unsupportedSuccessResponse(response, rawBody);
|
|
677
|
+
}
|
|
678
|
+
const size = parsed.size;
|
|
679
|
+
if (size !== void 0 && (typeof size !== "number" || !Number.isFinite(size) || !Number.isInteger(size) || size < 0)) throw unsupportedSuccessResponse(response, rawBody);
|
|
680
|
+
const requestId = requestIdFromHeaders(response.headers);
|
|
681
|
+
return {
|
|
682
|
+
type: "audio",
|
|
683
|
+
source: {
|
|
684
|
+
type: "url",
|
|
685
|
+
url: urlValue.trim()
|
|
686
|
+
},
|
|
687
|
+
meta: {
|
|
688
|
+
content_type: contentType,
|
|
689
|
+
...size !== void 0 ? { size } : {},
|
|
690
|
+
...requestId ? { request_id: requestId } : {}
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
async function generateAudioSpeech(input) {
|
|
695
|
+
const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, "/v1/audio/speech"), {
|
|
696
|
+
method: "POST",
|
|
697
|
+
headers: {
|
|
698
|
+
Authorization: `Bearer ${input.context.apiKey}`,
|
|
699
|
+
"Content-Type": "application/json"
|
|
700
|
+
},
|
|
701
|
+
body: JSON.stringify(buildPayload$2(input))
|
|
702
|
+
}, REQUEST_TIMEOUT_MS$6);
|
|
703
|
+
const rawBody = await response.text().catch(() => "");
|
|
704
|
+
if (!response.ok) throw providerError(response, rawBody);
|
|
705
|
+
return [parseSuccessResponse(response, rawBody)];
|
|
706
|
+
}
|
|
707
|
+
const audioSpeechAdapter = Object.assign(generateAudioSpeech, { validate: validateAudioSpeechRequest });
|
|
708
|
+
|
|
513
709
|
//#endregion
|
|
514
710
|
//#region src/adapters/gemini-generate-content.ts
|
|
515
|
-
const REQUEST_TIMEOUT_MS$
|
|
711
|
+
const REQUEST_TIMEOUT_MS$5 = 3e5;
|
|
516
712
|
const MARKDOWN_IMAGE_DATA_URI_PATTERN = /!\[[^\]]*\]\(data:([^;]+);base64,([^)]+)\)/;
|
|
517
713
|
function isHttpUrl(value) {
|
|
518
714
|
return value.startsWith("http://") || value.startsWith("https://");
|
|
@@ -627,7 +823,7 @@ async function geminiGenerateContentAdapter(input) {
|
|
|
627
823
|
"Content-Type": "application/json"
|
|
628
824
|
},
|
|
629
825
|
body: JSON.stringify(payload)
|
|
630
|
-
}, REQUEST_TIMEOUT_MS$
|
|
826
|
+
}, REQUEST_TIMEOUT_MS$5);
|
|
631
827
|
if (!response.ok) {
|
|
632
828
|
const body = await response.text().catch(() => response.statusText);
|
|
633
829
|
throw new GenerationProviderError("Gemini generation provider request failed", {
|
|
@@ -644,9 +840,9 @@ async function geminiGenerateContentAdapter(input) {
|
|
|
644
840
|
|
|
645
841
|
//#endregion
|
|
646
842
|
//#region src/adapters/kling-video-generations.ts
|
|
647
|
-
const REQUEST_TIMEOUT_MS$
|
|
648
|
-
const DEFAULT_POLL_INTERVAL_SEC$
|
|
649
|
-
const DEFAULT_MAX_WAIT_SEC$
|
|
843
|
+
const REQUEST_TIMEOUT_MS$4 = 186e4;
|
|
844
|
+
const DEFAULT_POLL_INTERVAL_SEC$2 = 5;
|
|
845
|
+
const DEFAULT_MAX_WAIT_SEC$2 = 900;
|
|
650
846
|
const KLING_MODELS = {
|
|
651
847
|
"kling-text-to-video": {
|
|
652
848
|
submitPath: "/kling/v1/videos/text2video",
|
|
@@ -670,19 +866,19 @@ const KLING_MODELS = {
|
|
|
670
866
|
imageMode: "multi"
|
|
671
867
|
}
|
|
672
868
|
};
|
|
673
|
-
function sleep$
|
|
869
|
+
function sleep$2(ms) {
|
|
674
870
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
675
871
|
}
|
|
676
|
-
function asString$
|
|
872
|
+
function asString$2(value) {
|
|
677
873
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
678
874
|
}
|
|
679
|
-
function asInteger$
|
|
875
|
+
function asInteger$2(value, fallback) {
|
|
680
876
|
return typeof value === "number" && Number.isInteger(value) ? value : fallback;
|
|
681
877
|
}
|
|
682
878
|
function asNumber(value) {
|
|
683
879
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
684
880
|
}
|
|
685
|
-
function isRecord$
|
|
881
|
+
function isRecord$4(value) {
|
|
686
882
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
687
883
|
}
|
|
688
884
|
function providerMeta(input) {
|
|
@@ -691,7 +887,7 @@ function providerMeta(input) {
|
|
|
691
887
|
delete rest.role;
|
|
692
888
|
return rest;
|
|
693
889
|
}
|
|
694
|
-
function normalizeStatus$
|
|
890
|
+
function normalizeStatus$2(value) {
|
|
695
891
|
const status = String(value ?? "").trim().toLowerCase();
|
|
696
892
|
if (status === "success" || status === "succeed" || status === "succeeded" || status === "completed") return "succeeded";
|
|
697
893
|
if (status === "queued" || status === "processing" || status === "in_progress" || status === "not_start" || status === "submitted") return "processing";
|
|
@@ -765,12 +961,12 @@ function buildPayload$1(input, model, prompt, images) {
|
|
|
765
961
|
model_name: model.defaultModelName
|
|
766
962
|
};
|
|
767
963
|
if (prompt) payload.prompt = prompt;
|
|
768
|
-
if (!payload.duration) payload.duration = String(asInteger$
|
|
769
|
-
if (!payload.mode) payload.mode = asString$
|
|
964
|
+
if (!payload.duration) payload.duration = String(asInteger$2(input.parameters.duration, 5));
|
|
965
|
+
if (!payload.mode) payload.mode = asString$2(input.parameters.mode) ?? "std";
|
|
770
966
|
if (payload.cfg_scale === void 0) payload.cfg_scale = asNumber(input.parameters.cfg_scale) ?? .5;
|
|
771
|
-
if (!payload.aspect_ratio) payload.aspect_ratio = asString$
|
|
772
|
-
if (payload.negative_prompt === void 0 && asString$
|
|
773
|
-
if (payload.sound === void 0 && asString$
|
|
967
|
+
if (!payload.aspect_ratio) payload.aspect_ratio = asString$2(input.parameters.aspect_ratio) ?? "16:9";
|
|
968
|
+
if (payload.negative_prompt === void 0 && asString$2(input.parameters.negative_prompt)) payload.negative_prompt = input.parameters.negative_prompt;
|
|
969
|
+
if (payload.sound === void 0 && asString$2(input.parameters.sound)) payload.sound = input.parameters.sound;
|
|
774
970
|
if (model.imageMode === "single" && images[0] && !hasPlainImagePayload(payload)) {
|
|
775
971
|
payload.image = images[0].url;
|
|
776
972
|
if (images[1] && payload.image_tail === void 0) payload.image_tail = images[1].url;
|
|
@@ -780,18 +976,18 @@ function buildPayload$1(input, model, prompt, images) {
|
|
|
780
976
|
if (payload.seed === void 0 && input.parameters.seed !== void 0) payload.seed = input.parameters.seed;
|
|
781
977
|
return payload;
|
|
782
978
|
}
|
|
783
|
-
function extractTaskId$
|
|
784
|
-
const taskId = asString$
|
|
979
|
+
function extractTaskId$2(response) {
|
|
980
|
+
const taskId = asString$2(response.task_id) ?? asString$2(response.id) ?? asString$2(response.data?.task_id) ?? asString$2(response.data?.id);
|
|
785
981
|
if (!taskId) throw new GenerationProviderError("Kling video provider did not return a task id", { details: { response } });
|
|
786
982
|
return taskId;
|
|
787
983
|
}
|
|
788
984
|
function extractStatus(response) {
|
|
789
985
|
const wrapper = response.data;
|
|
790
986
|
const native = wrapper?.data;
|
|
791
|
-
const status = normalizeStatus$
|
|
987
|
+
const status = normalizeStatus$2(native?.status ?? wrapper?.task_status ?? wrapper?.status ?? response.task_status ?? response.status);
|
|
792
988
|
const firstVideo = wrapper?.task_result?.videos?.[0] ?? native?.task_result?.videos?.[0];
|
|
793
|
-
const videoUrl = asString$
|
|
794
|
-
const message = asString$
|
|
989
|
+
const videoUrl = asString$2(firstVideo?.url) ?? asString$2(wrapper?.result_url) ?? asString$2(wrapper?.video_url) ?? asString$2(wrapper?.url) ?? asString$2(native?.content?.video_url) ?? asString$2(response.metadata?.url) ?? asString$2(response.result_url) ?? asString$2(response.video_url) ?? asString$2(response.url);
|
|
990
|
+
const message = asString$2(wrapper?.task_status_msg) ?? asString$2(response.error?.message) ?? asString$2(response.message);
|
|
795
991
|
return {
|
|
796
992
|
status,
|
|
797
993
|
videoUrl,
|
|
@@ -804,7 +1000,7 @@ function extractStatus(response) {
|
|
|
804
1000
|
})
|
|
805
1001
|
};
|
|
806
1002
|
}
|
|
807
|
-
async function requestJson$
|
|
1003
|
+
async function requestJson$2(input, path, init) {
|
|
808
1004
|
const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, path), {
|
|
809
1005
|
...init,
|
|
810
1006
|
headers: {
|
|
@@ -812,7 +1008,7 @@ async function requestJson$1(input, path, init) {
|
|
|
812
1008
|
"Content-Type": "application/json",
|
|
813
1009
|
...init.headers
|
|
814
1010
|
}
|
|
815
|
-
}, REQUEST_TIMEOUT_MS$
|
|
1011
|
+
}, REQUEST_TIMEOUT_MS$4);
|
|
816
1012
|
const body = await response.text();
|
|
817
1013
|
let parsed = {};
|
|
818
1014
|
try {
|
|
@@ -824,7 +1020,7 @@ async function requestJson$1(input, path, init) {
|
|
|
824
1020
|
});
|
|
825
1021
|
}
|
|
826
1022
|
if (!response.ok) {
|
|
827
|
-
const details = isRecord$
|
|
1023
|
+
const details = isRecord$4(parsed) ? { details: parsed } : {};
|
|
828
1024
|
throw new GenerationProviderError("Kling video provider request failed", {
|
|
829
1025
|
status: response.status,
|
|
830
1026
|
body,
|
|
@@ -842,16 +1038,16 @@ async function klingVideoGenerationsAdapter(input) {
|
|
|
842
1038
|
if (!prompt && model.allowPromptlessOmni && !hasPromptlessOmniPayload(meta, images)) throw new GenerationValidationError("Prompt text or Omni media input is required");
|
|
843
1039
|
if (model.imageMode === "single" && images.length === 0 && !hasPlainImagePayload(meta)) throw new GenerationValidationError("Image input is required");
|
|
844
1040
|
if (model.imageMode === "multi" && images.length === 0 && !hasMultiImagePayload(meta)) throw new GenerationValidationError("Multi-image input is required");
|
|
845
|
-
const taskId = extractTaskId$
|
|
1041
|
+
const taskId = extractTaskId$2(await requestJson$2(input, model.submitPath, {
|
|
846
1042
|
method: "POST",
|
|
847
1043
|
body: JSON.stringify(buildPayload$1(input, model, prompt, images))
|
|
848
1044
|
}));
|
|
849
|
-
const pollIntervalSec = asInteger$
|
|
850
|
-
const maxWaitSec = asInteger$
|
|
1045
|
+
const pollIntervalSec = asInteger$2(input.parameters.poll_interval, DEFAULT_POLL_INTERVAL_SEC$2);
|
|
1046
|
+
const maxWaitSec = asInteger$2(input.parameters.max_wait, DEFAULT_MAX_WAIT_SEC$2);
|
|
851
1047
|
const startedAt = Date.now();
|
|
852
1048
|
while (Date.now() - startedAt <= maxWaitSec * 1e3) {
|
|
853
|
-
await sleep$
|
|
854
|
-
const rawStatus = await requestJson$
|
|
1049
|
+
await sleep$2(pollIntervalSec * 1e3);
|
|
1050
|
+
const rawStatus = await requestJson$2(input, `${model.submitPath}/${encodeURIComponent(taskId)}`, { method: "GET" });
|
|
855
1051
|
const status = extractStatus(rawStatus);
|
|
856
1052
|
if (status.status === "succeeded") {
|
|
857
1053
|
if (!status.videoUrl) throw new GenerationProviderError("Kling video generation succeeded but returned no video URL", { details: compactObject({
|
|
@@ -881,6 +1077,268 @@ async function klingVideoGenerationsAdapter(input) {
|
|
|
881
1077
|
throw new GenerationTimeoutError("Timed out waiting for Kling video generation", { taskId });
|
|
882
1078
|
}
|
|
883
1079
|
|
|
1080
|
+
//#endregion
|
|
1081
|
+
//#region src/adapters/minimax-h3-video-generations.ts
|
|
1082
|
+
const REQUEST_TIMEOUT_MS$3 = 186e4;
|
|
1083
|
+
const DEFAULT_POLL_INTERVAL_SEC$1 = 2;
|
|
1084
|
+
const DEFAULT_MAX_WAIT_SEC$1 = 600;
|
|
1085
|
+
const MIN_DURATION_SEC = 4;
|
|
1086
|
+
const MAX_DURATION_SEC = 15;
|
|
1087
|
+
const MAX_MEDIA_COUNT = 12;
|
|
1088
|
+
const MAX_REFERENCE_IMAGES = 9;
|
|
1089
|
+
const MAX_REFERENCE_VIDEOS = 3;
|
|
1090
|
+
const MAX_REFERENCE_AUDIO = 3;
|
|
1091
|
+
const H3_RATIOS = [
|
|
1092
|
+
"adaptive",
|
|
1093
|
+
"21:9",
|
|
1094
|
+
"16:9",
|
|
1095
|
+
"4:3",
|
|
1096
|
+
"1:1",
|
|
1097
|
+
"3:4",
|
|
1098
|
+
"9:16"
|
|
1099
|
+
];
|
|
1100
|
+
function sleep$1(ms) {
|
|
1101
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1102
|
+
}
|
|
1103
|
+
function asString$1(value) {
|
|
1104
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1105
|
+
}
|
|
1106
|
+
function asInteger$1(value, fallback) {
|
|
1107
|
+
return typeof value === "number" && Number.isInteger(value) ? value : fallback;
|
|
1108
|
+
}
|
|
1109
|
+
function asBoolean(value, fallback) {
|
|
1110
|
+
return typeof value === "boolean" ? value : fallback;
|
|
1111
|
+
}
|
|
1112
|
+
function isRecord$3(value) {
|
|
1113
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1114
|
+
}
|
|
1115
|
+
function normalizeStatus$1(value) {
|
|
1116
|
+
const status = String(value ?? "").trim().toLowerCase();
|
|
1117
|
+
if ([
|
|
1118
|
+
"success",
|
|
1119
|
+
"succeed",
|
|
1120
|
+
"succeeded",
|
|
1121
|
+
"completed"
|
|
1122
|
+
].includes(status)) return "succeeded";
|
|
1123
|
+
if ([
|
|
1124
|
+
"queued",
|
|
1125
|
+
"processing",
|
|
1126
|
+
"in_progress",
|
|
1127
|
+
"running",
|
|
1128
|
+
"submitted",
|
|
1129
|
+
"not_start"
|
|
1130
|
+
].includes(status)) return "processing";
|
|
1131
|
+
if ([
|
|
1132
|
+
"failure",
|
|
1133
|
+
"failed",
|
|
1134
|
+
"error",
|
|
1135
|
+
"cancelled",
|
|
1136
|
+
"canceled",
|
|
1137
|
+
"expired"
|
|
1138
|
+
].includes(status)) return "failed";
|
|
1139
|
+
return status || "unknown";
|
|
1140
|
+
}
|
|
1141
|
+
function getMediaRole(block) {
|
|
1142
|
+
const role = getBlockMeta(block)?.role;
|
|
1143
|
+
return typeof role === "string" && role.trim() ? role.trim() : void 0;
|
|
1144
|
+
}
|
|
1145
|
+
function getH3InputMedia(input) {
|
|
1146
|
+
return input.request.content.filter((block) => block.type === "image" || block.type === "video" || block.type === "audio").map((block) => ({
|
|
1147
|
+
kind: block.type,
|
|
1148
|
+
source: block.source,
|
|
1149
|
+
role: getMediaRole(block)
|
|
1150
|
+
}));
|
|
1151
|
+
}
|
|
1152
|
+
function classifyMedia(media) {
|
|
1153
|
+
let firstFrames = 0;
|
|
1154
|
+
let lastFrames = 0;
|
|
1155
|
+
let referenceImages = 0;
|
|
1156
|
+
let referenceVideos = 0;
|
|
1157
|
+
let referenceAudio = 0;
|
|
1158
|
+
for (const item of media) {
|
|
1159
|
+
if (!item.role) throw new GenerationValidationError(`${item.kind} input must use a MiniMax H3 role`);
|
|
1160
|
+
if (item.kind === "image") if (item.role === "first_frame") firstFrames += 1;
|
|
1161
|
+
else if (item.role === "last_frame") lastFrames += 1;
|
|
1162
|
+
else if (item.role === "reference_image") referenceImages += 1;
|
|
1163
|
+
else throw new GenerationValidationError(`image role is not supported by MiniMax H3: ${item.role}`);
|
|
1164
|
+
else if (item.kind === "video") {
|
|
1165
|
+
if (item.role !== "reference_video") throw new GenerationValidationError(`video role must be reference_video for MiniMax H3`);
|
|
1166
|
+
referenceVideos += 1;
|
|
1167
|
+
} else {
|
|
1168
|
+
if (item.role !== "reference_audio") throw new GenerationValidationError(`audio role must be reference_audio for MiniMax H3`);
|
|
1169
|
+
referenceAudio += 1;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
if (firstFrames > 1 || lastFrames > 1) throw new GenerationValidationError("MiniMax H3 supports at most one first_frame and one last_frame image");
|
|
1173
|
+
if (referenceImages > MAX_REFERENCE_IMAGES) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_IMAGES} reference images`);
|
|
1174
|
+
if (referenceVideos > MAX_REFERENCE_VIDEOS) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_VIDEOS} reference videos`);
|
|
1175
|
+
if (referenceAudio > MAX_REFERENCE_AUDIO) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_AUDIO} reference audio files`);
|
|
1176
|
+
if (media.length > MAX_MEDIA_COUNT) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_MEDIA_COUNT} media items`);
|
|
1177
|
+
const hasFrames = firstFrames + lastFrames > 0;
|
|
1178
|
+
const hasReferences = referenceImages + referenceVideos + referenceAudio > 0;
|
|
1179
|
+
if (hasFrames && hasReferences) throw new GenerationValidationError("MiniMax H3 cannot mix frame images with reference materials");
|
|
1180
|
+
if (referenceAudio > 0 && referenceImages + referenceVideos === 0) throw new GenerationValidationError("MiniMax H3 reference audio requires a reference image or video");
|
|
1181
|
+
if (hasFrames) return "frame";
|
|
1182
|
+
if (hasReferences) return "reference";
|
|
1183
|
+
return "text";
|
|
1184
|
+
}
|
|
1185
|
+
async function resolveMedia(input, media) {
|
|
1186
|
+
return Promise.all(media.map(async (item) => ({
|
|
1187
|
+
kind: item.kind,
|
|
1188
|
+
role: item.role,
|
|
1189
|
+
url: await input.context.resolveSource(item.source)
|
|
1190
|
+
})));
|
|
1191
|
+
}
|
|
1192
|
+
function buildContent(prompt, media) {
|
|
1193
|
+
return [{
|
|
1194
|
+
type: "text",
|
|
1195
|
+
text: prompt
|
|
1196
|
+
}, ...media.map((item) => {
|
|
1197
|
+
if (item.kind === "image") return {
|
|
1198
|
+
type: "image_url",
|
|
1199
|
+
image_url: { url: item.url },
|
|
1200
|
+
role: item.role
|
|
1201
|
+
};
|
|
1202
|
+
if (item.kind === "video") return {
|
|
1203
|
+
type: "video_url",
|
|
1204
|
+
video_url: { url: item.url },
|
|
1205
|
+
role: item.role
|
|
1206
|
+
};
|
|
1207
|
+
return {
|
|
1208
|
+
type: "audio_url",
|
|
1209
|
+
audio_url: { url: item.url },
|
|
1210
|
+
role: item.role
|
|
1211
|
+
};
|
|
1212
|
+
})];
|
|
1213
|
+
}
|
|
1214
|
+
function resolveResolution(value) {
|
|
1215
|
+
const resolution = (asString$1(value) ?? "768P").toUpperCase();
|
|
1216
|
+
if (resolution !== "768P" && resolution !== "2K") throw new GenerationValidationError("MiniMax H3 resolution must be 768P or 2K");
|
|
1217
|
+
return resolution;
|
|
1218
|
+
}
|
|
1219
|
+
function resolveDuration(value) {
|
|
1220
|
+
const duration = asInteger$1(value, 5);
|
|
1221
|
+
if (duration < MIN_DURATION_SEC || duration > MAX_DURATION_SEC) throw new GenerationValidationError("MiniMax H3 duration must be an integer between 4 and 15");
|
|
1222
|
+
return duration;
|
|
1223
|
+
}
|
|
1224
|
+
function resolveRatio(value, mode) {
|
|
1225
|
+
const requested = asString$1(value) ?? "16:9";
|
|
1226
|
+
if (!H3_RATIOS.includes(requested)) throw new GenerationValidationError(`MiniMax H3 ratio must be one of: ${H3_RATIOS.join(", ")}`);
|
|
1227
|
+
if (mode === "text") {
|
|
1228
|
+
if (requested === "adaptive") throw new GenerationValidationError("MiniMax H3 text-to-video ratio cannot be adaptive");
|
|
1229
|
+
return requested;
|
|
1230
|
+
}
|
|
1231
|
+
return "adaptive";
|
|
1232
|
+
}
|
|
1233
|
+
function extractTaskId$1(response) {
|
|
1234
|
+
const data = isRecord$3(response.data) ? response.data : void 0;
|
|
1235
|
+
const taskId = asString$1(response.task_id) ?? asString$1(response.id) ?? asString$1(data?.task_id) ?? asString$1(data?.id);
|
|
1236
|
+
if (!taskId) throw new GenerationProviderError("MiniMax H3 provider did not return a task id", { details: { response } });
|
|
1237
|
+
return taskId;
|
|
1238
|
+
}
|
|
1239
|
+
function extractTaskStatus(response) {
|
|
1240
|
+
const task = isRecord$3(response.task) ? response.task : void 0;
|
|
1241
|
+
const metadata = isRecord$3(response.metadata) ? response.metadata : void 0;
|
|
1242
|
+
const content = isRecord$3(task?.content) ? task.content : void 0;
|
|
1243
|
+
const status = normalizeStatus$1(response.status ?? task?.status);
|
|
1244
|
+
const videoUrl = asString$1(metadata?.url) ?? asString$1(response.result_url) ?? asString$1(response.video_url) ?? asString$1(response.url) ?? asString$1(content?.url);
|
|
1245
|
+
const error = isRecord$3(response.error) ? response.error : isRecord$3(task?.error) ? task.error : void 0;
|
|
1246
|
+
const message = asString$1(error?.message) ?? asString$1(response.message) ?? asString$1(task?.message);
|
|
1247
|
+
const outputMetadata = compactObject({
|
|
1248
|
+
progress: response.progress ?? task?.progress,
|
|
1249
|
+
resolution: response.resolution ?? task?.resolution,
|
|
1250
|
+
duration: response.duration ?? task?.duration,
|
|
1251
|
+
ratio: response.ratio ?? task?.ratio
|
|
1252
|
+
});
|
|
1253
|
+
return {
|
|
1254
|
+
status: error && status === "unknown" ? "failed" : status,
|
|
1255
|
+
videoUrl,
|
|
1256
|
+
message,
|
|
1257
|
+
metadata: outputMetadata
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
async function requestJson$1(input, path, init) {
|
|
1261
|
+
const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, path), {
|
|
1262
|
+
...init,
|
|
1263
|
+
headers: {
|
|
1264
|
+
Authorization: `Bearer ${input.context.apiKey}`,
|
|
1265
|
+
"Content-Type": "application/json",
|
|
1266
|
+
...init.headers
|
|
1267
|
+
}
|
|
1268
|
+
}, REQUEST_TIMEOUT_MS$3);
|
|
1269
|
+
const body = await response.text();
|
|
1270
|
+
let parsed = {};
|
|
1271
|
+
try {
|
|
1272
|
+
parsed = body ? JSON.parse(body) : {};
|
|
1273
|
+
} catch {
|
|
1274
|
+
throw new GenerationProviderError("MiniMax H3 provider returned invalid JSON", {
|
|
1275
|
+
status: response.status,
|
|
1276
|
+
body
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
if (!response.ok) throw new GenerationProviderError("MiniMax H3 provider request failed", {
|
|
1280
|
+
status: response.status,
|
|
1281
|
+
body,
|
|
1282
|
+
...isRecord$3(parsed) ? { details: parsed } : {}
|
|
1283
|
+
});
|
|
1284
|
+
return parsed;
|
|
1285
|
+
}
|
|
1286
|
+
async function minimaxH3VideoGenerationsAdapter(input) {
|
|
1287
|
+
const prompt = mergeTextBlocks(input.declaration, input.request.content);
|
|
1288
|
+
if (!prompt) throw new GenerationValidationError("Prompt text is required");
|
|
1289
|
+
const inputMedia = getH3InputMedia(input);
|
|
1290
|
+
const mode = classifyMedia(inputMedia);
|
|
1291
|
+
const media = await resolveMedia(input, inputMedia);
|
|
1292
|
+
const duration = resolveDuration(input.parameters.duration);
|
|
1293
|
+
const resolution = resolveResolution(input.parameters.resolution);
|
|
1294
|
+
const ratio = resolveRatio(input.parameters.ratio, mode);
|
|
1295
|
+
const pollIntervalSec = Math.max(1, asInteger$1(input.parameters.poll_interval, DEFAULT_POLL_INTERVAL_SEC$1));
|
|
1296
|
+
const maxWaitSec = Math.max(30, asInteger$1(input.parameters.max_wait, DEFAULT_MAX_WAIT_SEC$1));
|
|
1297
|
+
const aigcWatermark = asBoolean(input.parameters.aigc_watermark, false);
|
|
1298
|
+
const payload = {
|
|
1299
|
+
model: input.declaration.model,
|
|
1300
|
+
content: buildContent(prompt, media),
|
|
1301
|
+
resolution,
|
|
1302
|
+
duration,
|
|
1303
|
+
ratio,
|
|
1304
|
+
aigc_watermark: aigcWatermark
|
|
1305
|
+
};
|
|
1306
|
+
const taskId = extractTaskId$1(await requestJson$1(input, "/v1/video/generations", {
|
|
1307
|
+
method: "POST",
|
|
1308
|
+
body: JSON.stringify(payload)
|
|
1309
|
+
}));
|
|
1310
|
+
const startedAt = Date.now();
|
|
1311
|
+
while (Date.now() - startedAt <= maxWaitSec * 1e3) {
|
|
1312
|
+
await sleep$1(pollIntervalSec * 1e3);
|
|
1313
|
+
const rawStatus = await requestJson$1(input, `/v1/video/generations/${encodeURIComponent(taskId)}`, { method: "GET" });
|
|
1314
|
+
const status = extractTaskStatus(rawStatus);
|
|
1315
|
+
if (status.status === "succeeded") {
|
|
1316
|
+
if (!status.videoUrl) throw new GenerationProviderError("MiniMax H3 generation succeeded but returned no video URL", { details: compactObject({
|
|
1317
|
+
taskId,
|
|
1318
|
+
rawStatus,
|
|
1319
|
+
metadata: status.metadata
|
|
1320
|
+
}) });
|
|
1321
|
+
return [{
|
|
1322
|
+
type: "video",
|
|
1323
|
+
source: {
|
|
1324
|
+
type: "url",
|
|
1325
|
+
url: status.videoUrl
|
|
1326
|
+
},
|
|
1327
|
+
meta: {
|
|
1328
|
+
task_id: taskId,
|
|
1329
|
+
status: status.status,
|
|
1330
|
+
...status.metadata
|
|
1331
|
+
}
|
|
1332
|
+
}];
|
|
1333
|
+
}
|
|
1334
|
+
if (status.status === "failed") throw new GenerationProviderError(`MiniMax H3 generation failed${status.message ? `: ${status.message}` : ""}`, { details: compactObject({
|
|
1335
|
+
taskId,
|
|
1336
|
+
rawStatus
|
|
1337
|
+
}) });
|
|
1338
|
+
}
|
|
1339
|
+
throw new GenerationTimeoutError("Timed out waiting for MiniMax H3 video generation", { taskId });
|
|
1340
|
+
}
|
|
1341
|
+
|
|
884
1342
|
//#endregion
|
|
885
1343
|
//#region src/adapters/openai-image-edits.ts
|
|
886
1344
|
const REQUEST_TIMEOUT_MS$2 = 3e5;
|
|
@@ -1391,14 +1849,19 @@ async function sunoTasksAdapter(input) {
|
|
|
1391
1849
|
//#region src/adapters/index.ts
|
|
1392
1850
|
const builtinGenerationAdapters = {
|
|
1393
1851
|
"ark.videoGenerations": arkVideoGenerationsAdapter,
|
|
1852
|
+
"openai.audioSpeech": audioSpeechAdapter,
|
|
1394
1853
|
"gemini.generateContent": geminiGenerateContentAdapter,
|
|
1395
1854
|
"kling.videoGenerations": klingVideoGenerationsAdapter,
|
|
1855
|
+
"minimax.h3VideoGenerations": minimaxH3VideoGenerationsAdapter,
|
|
1396
1856
|
"openai.imageEdits": openAiImageEditsAdapter,
|
|
1397
1857
|
"openai.images": openAiImagesAdapter,
|
|
1398
1858
|
"suno.tasks": sunoTasksAdapter
|
|
1399
1859
|
};
|
|
1860
|
+
function tryGetGenerationAdapter(type, adapters = {}) {
|
|
1861
|
+
return adapters[type] ?? builtinGenerationAdapters[type];
|
|
1862
|
+
}
|
|
1400
1863
|
function getGenerationAdapter(type, adapters = {}) {
|
|
1401
|
-
const adapter =
|
|
1864
|
+
const adapter = tryGetGenerationAdapter(type, adapters);
|
|
1402
1865
|
if (!adapter) throw new GenerationUnsupportedAdapterError(type);
|
|
1403
1866
|
return adapter;
|
|
1404
1867
|
}
|
|
@@ -1499,6 +1962,14 @@ function stringValue(value) {
|
|
|
1499
1962
|
function isRecord(value) {
|
|
1500
1963
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1501
1964
|
}
|
|
1965
|
+
function extractGenerationResultHeaderFields(headers) {
|
|
1966
|
+
const requestId = headers.get("x-request-id")?.trim() || void 0;
|
|
1967
|
+
const oneApiRequestId = headers.get("x-oneapi-request-id")?.trim() || void 0;
|
|
1968
|
+
return requestId || oneApiRequestId ? {
|
|
1969
|
+
...requestId ? { requestId } : {},
|
|
1970
|
+
...oneApiRequestId ? { oneApiRequestId } : {}
|
|
1971
|
+
} : void 0;
|
|
1972
|
+
}
|
|
1502
1973
|
function extractGenerationResultFields(raw) {
|
|
1503
1974
|
if (!isRecord(raw)) return void 0;
|
|
1504
1975
|
const usage = isRecord(raw.usage) ? raw.usage : void 0;
|
|
@@ -1594,11 +2065,13 @@ function resolveModels(options) {
|
|
|
1594
2065
|
function createResultFieldCaptureFetch(fetchFn, onFields) {
|
|
1595
2066
|
return (async (input, init) => {
|
|
1596
2067
|
const response = await fetchFn(input, init);
|
|
2068
|
+
const headerFields = extractGenerationResultHeaderFields(response.headers);
|
|
1597
2069
|
const contentType = response.headers.get("content-type") ?? "";
|
|
2070
|
+
let fields;
|
|
1598
2071
|
if (contentType.includes("application/json") || contentType.includes("+json")) try {
|
|
1599
|
-
|
|
1600
|
-
if (fields) onFields(fields);
|
|
2072
|
+
fields = extractGenerationResultFields(await response.clone().json());
|
|
1601
2073
|
} catch {}
|
|
2074
|
+
if (fields || headerFields) onFields(fields, headerFields);
|
|
1602
2075
|
return response;
|
|
1603
2076
|
});
|
|
1604
2077
|
}
|
|
@@ -1622,12 +2095,17 @@ function createGenerationClient(options = {}) {
|
|
|
1622
2095
|
...request.metadata ?? {},
|
|
1623
2096
|
...request.meta ?? {}
|
|
1624
2097
|
}, request.content), request.content);
|
|
1625
|
-
|
|
2098
|
+
const resolved = {
|
|
1626
2099
|
declaration: cloneJson(declaration),
|
|
1627
|
-
request
|
|
2100
|
+
request,
|
|
1628
2101
|
parameters,
|
|
1629
2102
|
meta
|
|
1630
2103
|
};
|
|
2104
|
+
tryGetGenerationAdapter(declaration.adapter.type, options.adapters)?.validate?.(resolved);
|
|
2105
|
+
return {
|
|
2106
|
+
...resolved,
|
|
2107
|
+
request: cloneJson(request)
|
|
2108
|
+
};
|
|
1631
2109
|
}
|
|
1632
2110
|
async function runAdapter(request, fetch) {
|
|
1633
2111
|
const resolved = validateRequest(request);
|
|
@@ -1652,12 +2130,23 @@ function createGenerationClient(options = {}) {
|
|
|
1652
2130
|
},
|
|
1653
2131
|
async generateResult(request) {
|
|
1654
2132
|
let capturedFields;
|
|
2133
|
+
let capturedBodyRequestId;
|
|
2134
|
+
let capturedRequestId;
|
|
2135
|
+
let capturedOneApiRequestId;
|
|
1655
2136
|
return {
|
|
1656
|
-
content: await runAdapter(request, createResultFieldCaptureFetch(adapterFetch, (fields) => {
|
|
1657
|
-
capturedFields = {
|
|
2137
|
+
content: await runAdapter(request, createResultFieldCaptureFetch(adapterFetch, (fields, headerFields) => {
|
|
2138
|
+
if (fields) capturedFields = {
|
|
1658
2139
|
...capturedFields,
|
|
1659
2140
|
...fields
|
|
1660
2141
|
};
|
|
2142
|
+
if (fields?.requestId) capturedBodyRequestId = fields.requestId;
|
|
2143
|
+
if (headerFields?.requestId) capturedRequestId = headerFields.requestId;
|
|
2144
|
+
if (headerFields?.oneApiRequestId) capturedOneApiRequestId = headerFields.oneApiRequestId;
|
|
2145
|
+
const requestId = capturedBodyRequestId ?? capturedRequestId ?? capturedOneApiRequestId;
|
|
2146
|
+
if (requestId) capturedFields = {
|
|
2147
|
+
...capturedFields,
|
|
2148
|
+
requestId
|
|
2149
|
+
};
|
|
1661
2150
|
})),
|
|
1662
2151
|
...capturedFields ?? {}
|
|
1663
2152
|
};
|
|
@@ -1717,5 +2206,5 @@ async function exportBuiltinModelConfigs(directory) {
|
|
|
1717
2206
|
}
|
|
1718
2207
|
|
|
1719
2208
|
//#endregion
|
|
1720
|
-
export {
|
|
1721
|
-
//# sourceMappingURL=export-config-
|
|
2209
|
+
export { resolveGenerationMeta as A, minimaxH3VideoGenerationsAdapter as C, arkVideoGenerationsAdapter as D, audioSpeechAdapter as E, GenerationProviderError as F, GenerationTimeoutError as I, GenerationUnsupportedAdapterError as L, validateGenerationContent as M, GenerationConfigError as N, mergeGenerationMeta as O, GenerationError as P, GenerationValidationError as R, openAiImageEditsAdapter as S, geminiGenerateContentAdapter as T, writeGenerationModelDeclarations as _, createGenerationClientFromDirectory as a, sunoTasksAdapter as b, defaultGenerationSourceResolver as c, parseGenerationModelDeclaration as d, readGenerationModelDeclaration as f, writeGenerationModelDeclaration as g, stringifyGenerationModelDeclaration as h, createGenerationClient as i, resolveGenerationParameters as j, mergeTextBlocks as k, isGenerationModelDeclaration as l, readGenerationModelDeclarationsFromFiles as m, exportBuiltinModelConfigs as n, createGenerationClientFromFile as o, readGenerationModelDeclarationsFromDirectory as p, stringifyBuiltinModelConfig as r, createGenerationClientFromFiles as s, exportBuiltinModelConfig as t, mergeGenerationModelDeclarations as u, builtinGenerationAdapters as v, klingVideoGenerationsAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y };
|
|
2210
|
+
//# sourceMappingURL=export-config-2OmCf-nP.js.map
|