@neta-art/generation 0.1.8 → 0.1.9
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 +26 -1
- package/dist/{builtins-BdNYdtm9.d.ts → builtins-CWEB_GK4.d.ts} +5 -2
- package/dist/builtins-CWEB_GK4.d.ts.map +1 -0
- package/dist/{builtins--2dnc9UT.js → builtins-CcfifHB4.js} +70 -34
- package/dist/builtins-CcfifHB4.js.map +1 -0
- package/dist/builtins.d.ts +1 -1
- package/dist/builtins.js +3 -2
- package/dist/cli/index.js +5 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/{export-config-BuQ5Maoj.js → export-config--lWA-0gu.js} +97 -39
- package/dist/export-config--lWA-0gu.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/models/seedance-2-0-fast.yaml +14 -2
- package/models/seedance-2-0.yaml +14 -2
- package/package.json +8 -7
- package/dist/builtins--2dnc9UT.js.map +0 -1
- package/dist/builtins-BdNYdtm9.d.ts.map +0 -1
- package/dist/export-config-BuQ5Maoj.js.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { a as
|
|
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-CcfifHB4.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";
|
|
5
|
+
|
|
5
6
|
//#region src/errors.ts
|
|
6
7
|
var GenerationError = class extends Error {
|
|
7
8
|
constructor(message) {
|
|
@@ -45,6 +46,7 @@ var GenerationTimeoutError = class extends GenerationProviderError {
|
|
|
45
46
|
this.name = "GenerationTimeoutError";
|
|
46
47
|
}
|
|
47
48
|
};
|
|
49
|
+
|
|
48
50
|
//#endregion
|
|
49
51
|
//#region src/http.ts
|
|
50
52
|
function headersToRecord(headers) {
|
|
@@ -132,6 +134,7 @@ async function fetchWithTimeout(fetchFn, url, init, timeoutMs) {
|
|
|
132
134
|
function joinUrl(baseUrl, path) {
|
|
133
135
|
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
134
136
|
}
|
|
137
|
+
|
|
135
138
|
//#endregion
|
|
136
139
|
//#region src/validation.ts
|
|
137
140
|
function specsByType(specs) {
|
|
@@ -139,6 +142,9 @@ function specsByType(specs) {
|
|
|
139
142
|
for (const spec of specs) map.set(spec.type, spec);
|
|
140
143
|
return map;
|
|
141
144
|
}
|
|
145
|
+
function getRole(block) {
|
|
146
|
+
return block.meta?.role;
|
|
147
|
+
}
|
|
142
148
|
function validateGenerationContent(declaration, content) {
|
|
143
149
|
const inputSpecs = specsByType(declaration.content.input);
|
|
144
150
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -147,6 +153,11 @@ function validateGenerationContent(declaration, content) {
|
|
|
147
153
|
if (!spec) throw new GenerationValidationError(`Content block type is not supported by ${declaration.model}: ${block.type}`);
|
|
148
154
|
counts.set(block.type, (counts.get(block.type) ?? 0) + 1);
|
|
149
155
|
if ("source" in block && spec.sources && !spec.sources.includes(block.source.type)) throw new GenerationValidationError(`${block.type} source is not supported by ${declaration.model}: ${block.source.type}`);
|
|
156
|
+
const role = getRole(block);
|
|
157
|
+
if (spec.roleRequired && (typeof role !== "string" || role.length === 0)) throw new GenerationValidationError(`${block.type} role is required by ${declaration.model}`);
|
|
158
|
+
if (role !== void 0 && spec.roles) {
|
|
159
|
+
if (typeof role !== "string" || role.length === 0 || !spec.roles.includes(role)) throw new GenerationValidationError(`${block.type} role is not supported by ${declaration.model}: ${String(role)}`);
|
|
160
|
+
}
|
|
150
161
|
}
|
|
151
162
|
for (const spec of declaration.content.input) {
|
|
152
163
|
const count = counts.get(spec.type) ?? 0;
|
|
@@ -245,6 +256,7 @@ function mergeTextBlocks(declaration, content) {
|
|
|
245
256
|
const separator = textSpec?.merge === "space" ? " " : textSpec?.merge === "concat" ? "" : "\n";
|
|
246
257
|
return content.filter((block) => block.type === "text").map((block) => block.text).join(separator).trim();
|
|
247
258
|
}
|
|
259
|
+
|
|
248
260
|
//#endregion
|
|
249
261
|
//#region src/adapters/ark-video-generations.ts
|
|
250
262
|
const REQUEST_TIMEOUT_MS$5 = 186e4;
|
|
@@ -300,39 +312,73 @@ function resolveSize(resolution, aspectRatio) {
|
|
|
300
312
|
height: height % 2 === 0 ? height : height + 1
|
|
301
313
|
};
|
|
302
314
|
}
|
|
303
|
-
function
|
|
315
|
+
function getMediaRole(block) {
|
|
304
316
|
const role = getBlockMeta(block)?.role;
|
|
305
317
|
return typeof role === "string" && role ? role : void 0;
|
|
306
318
|
}
|
|
307
|
-
function
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
319
|
+
function isFrameImage(item) {
|
|
320
|
+
return item.kind === "image" && (item.role === "first_frame" || item.role === "last_frame");
|
|
321
|
+
}
|
|
322
|
+
function isReferenceMedia(item) {
|
|
323
|
+
return item.kind === "image" && item.role === "reference_image" || item.kind === "video" && item.role === "reference_video";
|
|
324
|
+
}
|
|
325
|
+
function assertSingleRole(media, role, message) {
|
|
326
|
+
if (media.filter((item) => item.role === role).length > 1) throw new GenerationValidationError(message);
|
|
327
|
+
}
|
|
328
|
+
function classifyMedia(media) {
|
|
329
|
+
if (media.length === 0) return null;
|
|
330
|
+
for (const item of media) {
|
|
331
|
+
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");
|
|
332
|
+
if (item.kind === "video" && item.role !== "reference_video") throw new GenerationValidationError("Video input must use meta.role reference_video");
|
|
333
|
+
}
|
|
334
|
+
const hasFrame = media.some(isFrameImage);
|
|
335
|
+
const hasReference = media.some(isReferenceMedia);
|
|
336
|
+
const hasPlain = media.some((item) => item.kind === "image" && !item.role);
|
|
311
337
|
if ([
|
|
312
|
-
|
|
313
|
-
|
|
338
|
+
hasPlain,
|
|
339
|
+
hasFrame,
|
|
314
340
|
hasReference
|
|
315
|
-
].filter(Boolean).length > 1) throw new GenerationValidationError("Cannot mix video
|
|
316
|
-
if (hasReference)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (
|
|
327
|
-
|
|
328
|
-
|
|
341
|
+
].filter(Boolean).length > 1) throw new GenerationValidationError("Cannot mix video media modes: use only plain image, first_frame/last_frame, or reference_image/reference_video");
|
|
342
|
+
if (hasReference) {
|
|
343
|
+
assertSingleRole(media, "reference_video", "Reference mode supports at most one reference_video");
|
|
344
|
+
return "reference";
|
|
345
|
+
}
|
|
346
|
+
if (hasFrame) {
|
|
347
|
+
assertSingleRole(media, "first_frame", "Frame mode supports at most one first_frame image");
|
|
348
|
+
assertSingleRole(media, "last_frame", "Frame mode supports at most one last_frame image");
|
|
349
|
+
return "frame";
|
|
350
|
+
}
|
|
351
|
+
if (hasPlain) {
|
|
352
|
+
if (media.filter((item) => item.kind === "image" && !item.role).length > 1) throw new GenerationValidationError("Plain image mode supports at most one image");
|
|
353
|
+
return "image";
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
function buildMetadataContent(media, mode) {
|
|
358
|
+
const content = [];
|
|
359
|
+
for (const item of media) {
|
|
360
|
+
if (mode === "frame" && (item.kind !== "image" || item.role !== "first_frame" && item.role !== "last_frame")) throw new GenerationValidationError("Frame mode images must use meta.role first_frame or last_frame");
|
|
361
|
+
if (mode === "reference" && !(item.kind === "image" && item.role === "reference_image" || item.kind === "video" && item.role === "reference_video")) throw new GenerationValidationError("Reference mode media must use meta.role reference_image or reference_video");
|
|
362
|
+
if (item.kind === "image") content.push({
|
|
329
363
|
type: "image_url",
|
|
330
|
-
image_url: { url:
|
|
331
|
-
role:
|
|
364
|
+
image_url: { url: item.url },
|
|
365
|
+
role: item.role
|
|
366
|
+
});
|
|
367
|
+
else content.push({
|
|
368
|
+
type: "video_url",
|
|
369
|
+
video_url: { url: item.url },
|
|
370
|
+
role: item.role
|
|
332
371
|
});
|
|
333
372
|
}
|
|
334
373
|
return content;
|
|
335
374
|
}
|
|
375
|
+
async function resolveMedia(input, media) {
|
|
376
|
+
return Promise.all(media.map(async (item) => ({
|
|
377
|
+
kind: item.kind,
|
|
378
|
+
role: item.role,
|
|
379
|
+
url: await input.context.resolveSource(item.source)
|
|
380
|
+
})));
|
|
381
|
+
}
|
|
336
382
|
function extractTaskId$2(response) {
|
|
337
383
|
const taskId = asString$2(response.task_id) ?? asString$2(response.id);
|
|
338
384
|
if (!taskId) throw new GenerationProviderError("Video generation provider did not return a task id", { details: { response } });
|
|
@@ -392,12 +438,13 @@ async function requestJson$2(input, path, init) {
|
|
|
392
438
|
async function arkVideoGenerationsAdapter(input) {
|
|
393
439
|
const prompt = mergeTextBlocks(input.declaration, input.request.content);
|
|
394
440
|
if (!prompt) throw new GenerationValidationError("Prompt text is required");
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
role:
|
|
399
|
-
}))
|
|
400
|
-
const mode =
|
|
441
|
+
const inputMedia = input.request.content.filter((block) => block.type === "image" || block.type === "video").map((block) => ({
|
|
442
|
+
kind: block.type,
|
|
443
|
+
source: block.source,
|
|
444
|
+
role: getMediaRole(block)
|
|
445
|
+
}));
|
|
446
|
+
const mode = classifyMedia(inputMedia);
|
|
447
|
+
const media = await resolveMedia(input, inputMedia);
|
|
401
448
|
const resolution = asString$2(input.parameters.resolution) ?? "720p";
|
|
402
449
|
const aspectRatio = asString$2(input.parameters.aspect_ratio) ?? "16:9";
|
|
403
450
|
const duration = getIntegerParameter(input.parameters, "duration", 5);
|
|
@@ -423,7 +470,7 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
423
470
|
if (cameraFixed) metadata.camera_fixed = true;
|
|
424
471
|
if (watermark) metadata.watermark = true;
|
|
425
472
|
if (mode === "frame" || mode === "reference") {
|
|
426
|
-
metadata.content = buildMetadataContent(
|
|
473
|
+
metadata.content = buildMetadataContent(media, mode);
|
|
427
474
|
metadata.resolution = resolution;
|
|
428
475
|
metadata.ratio = aspectRatio;
|
|
429
476
|
} else {
|
|
@@ -432,7 +479,8 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
432
479
|
payload.width = size.width;
|
|
433
480
|
payload.height = size.height;
|
|
434
481
|
}
|
|
435
|
-
|
|
482
|
+
const firstImage = media.find((item) => item.kind === "image");
|
|
483
|
+
if (firstImage) payload.image = firstImage.url;
|
|
436
484
|
}
|
|
437
485
|
payload.metadata = metadata;
|
|
438
486
|
const taskId = extractTaskId$2(await requestJson$2(input, "/v1/video/generations", {
|
|
@@ -486,6 +534,7 @@ async function arkVideoGenerationsAdapter(input) {
|
|
|
486
534
|
}
|
|
487
535
|
throw new GenerationTimeoutError("Timed out waiting for video generation", { taskId });
|
|
488
536
|
}
|
|
537
|
+
|
|
489
538
|
//#endregion
|
|
490
539
|
//#region src/adapters/gemini-generate-content.ts
|
|
491
540
|
const REQUEST_TIMEOUT_MS$4 = 3e5;
|
|
@@ -617,6 +666,7 @@ async function geminiGenerateContentAdapter(input) {
|
|
|
617
666
|
if (output.length === 0) throw new GenerationProviderError("Gemini generation returned no output", { details: collectGeminiNoOutputDetails(raw) });
|
|
618
667
|
return output;
|
|
619
668
|
}
|
|
669
|
+
|
|
620
670
|
//#endregion
|
|
621
671
|
//#region src/adapters/kling-video-generations.ts
|
|
622
672
|
const REQUEST_TIMEOUT_MS$3 = 186e4;
|
|
@@ -855,6 +905,7 @@ async function klingVideoGenerationsAdapter(input) {
|
|
|
855
905
|
}
|
|
856
906
|
throw new GenerationTimeoutError("Timed out waiting for Kling video generation", { taskId });
|
|
857
907
|
}
|
|
908
|
+
|
|
858
909
|
//#endregion
|
|
859
910
|
//#region src/adapters/openai-image-edits.ts
|
|
860
911
|
const REQUEST_TIMEOUT_MS$2 = 3e5;
|
|
@@ -924,6 +975,7 @@ async function openAiImageEditsAdapter(input) {
|
|
|
924
975
|
if (output.length === 0) throw new GenerationProviderError("Image edit returned no output", { details: collectOpenAiImageEditsNoOutputDetails(raw) });
|
|
925
976
|
return output;
|
|
926
977
|
}
|
|
978
|
+
|
|
927
979
|
//#endregion
|
|
928
980
|
//#region src/adapters/openai-images.ts
|
|
929
981
|
const REQUEST_TIMEOUT_MS$1 = 3e5;
|
|
@@ -1000,6 +1052,7 @@ async function openAiImagesAdapter(input) {
|
|
|
1000
1052
|
if (output.length === 0) throw new GenerationProviderError("Image generation returned no output", { details: collectOpenAiImagesNoOutputDetails(raw) });
|
|
1001
1053
|
return output;
|
|
1002
1054
|
}
|
|
1055
|
+
|
|
1003
1056
|
//#endregion
|
|
1004
1057
|
//#region src/adapters/suno-tasks.ts
|
|
1005
1058
|
const REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -1034,12 +1087,12 @@ const OPERATION_PATHS = {
|
|
|
1034
1087
|
poll: true
|
|
1035
1088
|
}
|
|
1036
1089
|
};
|
|
1037
|
-
const FINAL_SUCCESS_STATUSES =
|
|
1090
|
+
const FINAL_SUCCESS_STATUSES = new Set([
|
|
1038
1091
|
"success",
|
|
1039
1092
|
"succeeded",
|
|
1040
1093
|
"completed"
|
|
1041
1094
|
]);
|
|
1042
|
-
const FINAL_FAILURE_STATUSES =
|
|
1095
|
+
const FINAL_FAILURE_STATUSES = new Set([
|
|
1043
1096
|
"failure",
|
|
1044
1097
|
"failed",
|
|
1045
1098
|
"error",
|
|
@@ -1358,6 +1411,7 @@ async function sunoTasksAdapter(input) {
|
|
|
1358
1411
|
if (!taskId) return buildImmediateResult(operation, data, raw);
|
|
1359
1412
|
return pollSunoTask(input, operation, taskId, asInteger(input.parameters.poll_interval, DEFAULT_POLL_INTERVAL_SEC), asInteger(input.parameters.max_wait, DEFAULT_MAX_WAIT_SEC));
|
|
1360
1413
|
}
|
|
1414
|
+
|
|
1361
1415
|
//#endregion
|
|
1362
1416
|
//#region src/adapters/index.ts
|
|
1363
1417
|
const builtinGenerationAdapters = {
|
|
@@ -1373,9 +1427,10 @@ function getGenerationAdapter(type, adapters = {}) {
|
|
|
1373
1427
|
if (!adapter) throw new GenerationUnsupportedAdapterError(type);
|
|
1374
1428
|
return adapter;
|
|
1375
1429
|
}
|
|
1430
|
+
|
|
1376
1431
|
//#endregion
|
|
1377
1432
|
//#region src/config.ts
|
|
1378
|
-
const DECLARATION_EXTENSIONS =
|
|
1433
|
+
const DECLARATION_EXTENSIONS = new Set([
|
|
1379
1434
|
".yaml",
|
|
1380
1435
|
".yml",
|
|
1381
1436
|
".json"
|
|
@@ -1411,7 +1466,7 @@ function isGenerationModelDeclaration(value) {
|
|
|
1411
1466
|
const parameters = value.parameters;
|
|
1412
1467
|
const meta = value.meta;
|
|
1413
1468
|
const examples = value.examples;
|
|
1414
|
-
return value.schema ===
|
|
1469
|
+
return value.schema === MODEL_SCHEMA && typeof value.model === "string" && value.model.trim().length > 0 && (value.allowUnknownParameters === void 0 || typeof value.allowUnknownParameters === "boolean") && isRecord(adapter) && typeof adapter.type === "string" && isRecord(content) && Array.isArray(content.input) && (parameters === void 0 || isRecord(parameters) && Object.values(parameters).every(isParameterSpec)) && (meta === void 0 || isMetaSpec(meta)) && (examples === void 0 || Array.isArray(examples));
|
|
1415
1470
|
}
|
|
1416
1471
|
function parseGenerationModelDeclaration(rawText, filePath = "model.yaml") {
|
|
1417
1472
|
const parsed = extname(filePath) === ".json" ? JSON.parse(rawText) : parse(rawText);
|
|
@@ -1445,6 +1500,7 @@ async function writeGenerationModelDeclarations(declarations, directory, options
|
|
|
1445
1500
|
const ext = options.format === "json" ? "json" : "yaml";
|
|
1446
1501
|
await Promise.all(declarations.map((declaration) => writeGenerationModelDeclaration(declaration, join(directory, `${slugifyFileName(declaration.model)}.${ext}`), options)));
|
|
1447
1502
|
}
|
|
1503
|
+
|
|
1448
1504
|
//#endregion
|
|
1449
1505
|
//#region src/source.ts
|
|
1450
1506
|
const defaultGenerationSourceResolver = (source) => {
|
|
@@ -1453,13 +1509,14 @@ const defaultGenerationSourceResolver = (source) => {
|
|
|
1453
1509
|
case "base64": return `data:${source.mediaType};base64,${source.data}`;
|
|
1454
1510
|
}
|
|
1455
1511
|
};
|
|
1512
|
+
|
|
1456
1513
|
//#endregion
|
|
1457
1514
|
//#region src/client.ts
|
|
1458
1515
|
const DEFAULT_BASE_URL = "https://router.neta.art";
|
|
1459
1516
|
const REDACTED = "[REDACTED]";
|
|
1460
1517
|
const SECRET_DEBUG_KEY_PATTERN = /^(authorization|api[-_]?key|token|thoughtSignature)$/i;
|
|
1461
1518
|
const BASE64_DEBUG_KEY_PATTERN = /^(b64_json|data)$/i;
|
|
1462
|
-
const MEDIA_PAYLOAD_KEYS =
|
|
1519
|
+
const MEDIA_PAYLOAD_KEYS = new Set([
|
|
1463
1520
|
"audio",
|
|
1464
1521
|
"audio_url",
|
|
1465
1522
|
"image",
|
|
@@ -1604,6 +1661,7 @@ async function createGenerationClientFromDirectory(directory, options = {}) {
|
|
|
1604
1661
|
async function createGenerationClientFromFile(filePath, options = {}) {
|
|
1605
1662
|
return createGenerationClientFromFiles([filePath], options);
|
|
1606
1663
|
}
|
|
1664
|
+
|
|
1607
1665
|
//#endregion
|
|
1608
1666
|
//#region src/export-config.ts
|
|
1609
1667
|
function stringifyBuiltinModelConfig(model, options = {}) {
|
|
@@ -1619,7 +1677,7 @@ async function exportBuiltinModelConfig(model, filePath) {
|
|
|
1619
1677
|
async function exportBuiltinModelConfigs(directory) {
|
|
1620
1678
|
await writeGenerationModelDeclarations(listBuiltinGenerationModels(), directory);
|
|
1621
1679
|
}
|
|
1680
|
+
|
|
1622
1681
|
//#endregion
|
|
1623
1682
|
export { validateGenerationContent as A, klingVideoGenerationsAdapter as C, mergeTextBlocks as D, mergeGenerationMeta as E, GenerationUnsupportedAdapterError as F, GenerationValidationError as I, GenerationError as M, GenerationProviderError as N, resolveGenerationMeta as O, GenerationTimeoutError as P, openAiImageEditsAdapter as S, arkVideoGenerationsAdapter 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, GenerationConfigError as j, resolveGenerationParameters 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, geminiGenerateContentAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y };
|
|
1624
|
-
|
|
1625
|
-
//# sourceMappingURL=export-config-BuQ5Maoj.js.map
|
|
1683
|
+
//# sourceMappingURL=export-config--lWA-0gu.js.map
|