@neta-art/generation 0.1.4 → 0.1.6

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.
Files changed (37) hide show
  1. package/README.md +97 -14
  2. package/dist/{builtins-BJ2_TVlr.d.ts → builtins-C-_aGhT8.d.ts} +2 -2
  3. package/dist/builtins-C-_aGhT8.d.ts.map +1 -0
  4. package/dist/builtins-NAtI9FFU.js +1186 -0
  5. package/dist/builtins-NAtI9FFU.js.map +1 -0
  6. package/dist/builtins.d.ts +1 -1
  7. package/dist/builtins.js +1 -1
  8. package/dist/cli/index.js +2 -2
  9. package/dist/{export-config-D8By2_r7.js → export-config-DS2XD-tF.js} +443 -44
  10. package/dist/export-config-DS2XD-tF.js.map +1 -0
  11. package/dist/index.d.ts +8 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -3
  14. package/models/birefnet-general.yaml +25 -0
  15. package/models/kling-image-to-video.yaml +89 -0
  16. package/models/kling-multi-image-to-video.yaml +93 -0
  17. package/models/kling-omni-video.yaml +107 -0
  18. package/models/kling-text-to-video.yaml +79 -0
  19. package/models/noobxl-i2i-ipa-onediff.yaml +72 -0
  20. package/models/noobxl-t2i-onediff.yaml +44 -0
  21. package/models/qwen-image-edit.yaml +44 -0
  22. package/models/suno_cover_chirp_v5.yaml +159 -0
  23. package/models/suno_image_to_song_chirp_v5.yaml +152 -0
  24. package/models/suno_infill_chirp_v5.yaml +148 -0
  25. package/models/suno_music_chirp_fenix.yaml +77 -0
  26. package/models/suno_sound_chirp_v5.yaml +145 -0
  27. package/models/suno_style_tags.yaml +14 -0
  28. package/models/suno_upload_audio.yaml +44 -0
  29. package/models/suno_video_to_song_chirp_v5.yaml +152 -0
  30. package/models/suno_vox_chirp_v5.yaml +149 -0
  31. package/models/z-image-turbo.yaml +34 -0
  32. package/package.json +19 -15
  33. package/dist/builtins-BJ2_TVlr.d.ts.map +0 -1
  34. package/dist/builtins-FumzmWvj.js +0 -565
  35. package/dist/builtins-FumzmWvj.js.map +0 -1
  36. package/dist/export-config-D8By2_r7.js.map +0 -1
  37. package/models/suno_music.yaml +0 -265
@@ -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-FumzmWvj.js";
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-NAtI9FFU.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";
@@ -251,9 +251,9 @@ function mergeTextBlocks(declaration, content) {
251
251
 
252
252
  //#endregion
253
253
  //#region src/adapters/ark-video-generations.ts
254
- const REQUEST_TIMEOUT_MS$3 = 6e4;
255
- const DEFAULT_POLL_INTERVAL_SEC$1 = 2;
256
- const DEFAULT_MAX_WAIT_SEC$1 = 600;
254
+ const REQUEST_TIMEOUT_MS$5 = 6e4;
255
+ const DEFAULT_POLL_INTERVAL_SEC$2 = 2;
256
+ const DEFAULT_MAX_WAIT_SEC$2 = 600;
257
257
  const RESOLUTION_SHORT_EDGE = {
258
258
  "480p": 480,
259
259
  "720p": 720,
@@ -271,19 +271,19 @@ const ASPECT_RATIOS = {
271
271
  "21:9": [21, 9],
272
272
  adaptive: null
273
273
  };
274
- function sleep$1(ms) {
274
+ function sleep$2(ms) {
275
275
  return new Promise((resolve) => setTimeout(resolve, ms));
276
276
  }
277
- function asString$1(value) {
277
+ function asString$2(value) {
278
278
  return typeof value === "string" && value ? value : void 0;
279
279
  }
280
- function asNumber(value) {
280
+ function asNumber$1(value) {
281
281
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
282
282
  }
283
283
  function asBoolean(value) {
284
284
  return typeof value === "boolean" ? value : void 0;
285
285
  }
286
- function normalizeStatus$1(value) {
286
+ function normalizeStatus$2(value) {
287
287
  const status = value.toLowerCase();
288
288
  return status === "success" ? "succeeded" : status;
289
289
  }
@@ -304,7 +304,7 @@ function resolveSize(resolution, aspectRatio) {
304
304
  height: height % 2 === 0 ? height : height + 1
305
305
  };
306
306
  }
307
- function getImageRole(block) {
307
+ function getImageRole$1(block) {
308
308
  const role = getBlockMeta(block)?.role;
309
309
  return typeof role === "string" && role ? role : void 0;
310
310
  }
@@ -337,8 +337,8 @@ function buildMetadataContent(prompt, images, mode) {
337
337
  }
338
338
  return content;
339
339
  }
340
- function extractTaskId$1(response) {
341
- const taskId = asString$1(response.task_id) ?? asString$1(response.id);
340
+ function extractTaskId$2(response) {
341
+ const taskId = asString$2(response.task_id) ?? asString$2(response.id);
342
342
  if (!taskId) throw new GenerationProviderError("Video generation provider did not return a task id", { details: { response } });
343
343
  return taskId;
344
344
  }
@@ -346,9 +346,9 @@ function normalizeTaskStatus(response) {
346
346
  if (response.data) {
347
347
  const wrapper = response.data;
348
348
  const native = wrapper.data;
349
- const status = normalizeStatus$1(asString$1(native?.status) ?? asString$1(wrapper.status) ?? "unknown");
350
- const videoUrl = asString$1(wrapper.result_url) ?? asString$1(native?.content?.video_url);
351
- const lastFrameUrl = asString$1(wrapper.first_frame) ?? asString$1(native?.content?.first_frame);
349
+ const status = normalizeStatus$2(asString$2(native?.status) ?? asString$2(wrapper.status) ?? "unknown");
350
+ const videoUrl = asString$2(wrapper.result_url) ?? asString$2(native?.content?.video_url);
351
+ const lastFrameUrl = asString$2(wrapper.first_frame) ?? asString$2(native?.content?.first_frame);
352
352
  const metadata = {
353
353
  progress: wrapper.progress,
354
354
  resolution: native?.resolution,
@@ -375,7 +375,7 @@ function normalizeTaskStatus(response) {
375
375
  metadata: {}
376
376
  };
377
377
  }
378
- async function requestJson$1(input, path, init) {
378
+ async function requestJson$2(input, path, init) {
379
379
  const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, path), {
380
380
  ...init,
381
381
  headers: {
@@ -383,7 +383,7 @@ async function requestJson$1(input, path, init) {
383
383
  "Content-Type": "application/json",
384
384
  ...init.headers
385
385
  }
386
- }, REQUEST_TIMEOUT_MS$3);
386
+ }, REQUEST_TIMEOUT_MS$5);
387
387
  if (!response.ok) {
388
388
  const body = await response.text().catch(() => response.statusText);
389
389
  throw new GenerationProviderError("Video generation provider request failed", {
@@ -399,20 +399,20 @@ async function arkVideoGenerationsAdapter(input) {
399
399
  const imageBlocks = input.request.content.filter((block) => block.type === "image");
400
400
  const images = await Promise.all(imageBlocks.map(async (block) => ({
401
401
  url: await input.context.resolveSource(block.source),
402
- role: getImageRole(block)
402
+ role: getImageRole$1(block)
403
403
  })));
404
404
  const mode = classifyImages(images);
405
- const resolution = asString$1(input.parameters.resolution) ?? "720p";
406
- const aspectRatio = asString$1(input.parameters.aspect_ratio) ?? "16:9";
405
+ const resolution = asString$2(input.parameters.resolution) ?? "720p";
406
+ const aspectRatio = asString$2(input.parameters.aspect_ratio) ?? "16:9";
407
407
  const duration = getIntegerParameter(input.parameters, "duration", 5);
408
408
  const fps = getIntegerParameter(input.parameters, "fps", 30);
409
- const pollIntervalSec = getIntegerParameter(input.parameters, "poll_interval", DEFAULT_POLL_INTERVAL_SEC$1);
410
- const maxWaitSec = getIntegerParameter(input.parameters, "max_wait", DEFAULT_MAX_WAIT_SEC$1);
409
+ const pollIntervalSec = getIntegerParameter(input.parameters, "poll_interval", DEFAULT_POLL_INTERVAL_SEC$2);
410
+ const maxWaitSec = getIntegerParameter(input.parameters, "max_wait", DEFAULT_MAX_WAIT_SEC$2);
411
411
  const generateAudio = asBoolean(input.parameters.generate_audio) ?? true;
412
412
  const returnLastFrame = asBoolean(input.parameters.return_last_frame) ?? true;
413
413
  const cameraFixed = asBoolean(input.parameters.camera_fixed) ?? false;
414
414
  const watermark = asBoolean(input.parameters.watermark) ?? false;
415
- const seed = asNumber(input.parameters.seed);
415
+ const seed = asNumber$1(input.parameters.seed);
416
416
  const payload = {
417
417
  model: input.declaration.model,
418
418
  prompt
@@ -439,14 +439,14 @@ async function arkVideoGenerationsAdapter(input) {
439
439
  if (images[0]) payload.image = images[0].url;
440
440
  }
441
441
  payload.metadata = metadata;
442
- const taskId = extractTaskId$1(await requestJson$1(input, "/v1/video/generations", {
442
+ const taskId = extractTaskId$2(await requestJson$2(input, "/v1/video/generations", {
443
443
  method: "POST",
444
444
  body: JSON.stringify(payload)
445
445
  }));
446
446
  const startedAt = Date.now();
447
447
  while (Date.now() - startedAt <= maxWaitSec * 1e3) {
448
- await sleep$1(pollIntervalSec * 1e3);
449
- const rawStatus = await requestJson$1(input, `/v1/video/generations/${encodeURIComponent(taskId)}`, { method: "GET" });
448
+ await sleep$2(pollIntervalSec * 1e3);
449
+ const rawStatus = await requestJson$2(input, `/v1/video/generations/${encodeURIComponent(taskId)}`, { method: "GET" });
450
450
  const status = normalizeTaskStatus(rawStatus);
451
451
  if (status.status === "succeeded") {
452
452
  if (!status.videoUrl) throw new GenerationProviderError("Video generation succeeded but returned no video URL", { details: compactObject({
@@ -493,7 +493,7 @@ async function arkVideoGenerationsAdapter(input) {
493
493
 
494
494
  //#endregion
495
495
  //#region src/adapters/gemini-generate-content.ts
496
- const REQUEST_TIMEOUT_MS$2 = 3e5;
496
+ const REQUEST_TIMEOUT_MS$4 = 3e5;
497
497
  const IMAGE_FETCH_TIMEOUT_MS = 6e4;
498
498
  const MAX_REFERENCE_IMAGE_BYTES = 10 * 1024 * 1024;
499
499
  const DATA_URI_PATTERN = /^data:([^;]+);base64,(.+)$/s;
@@ -631,7 +631,7 @@ async function geminiGenerateContentAdapter(input) {
631
631
  "Content-Type": "application/json"
632
632
  },
633
633
  body: JSON.stringify(payload)
634
- }, REQUEST_TIMEOUT_MS$2);
634
+ }, REQUEST_TIMEOUT_MS$4);
635
635
  if (!response.ok) {
636
636
  const body = await response.text().catch(() => response.statusText);
637
637
  throw new GenerationProviderError("Gemini generation provider request failed", {
@@ -646,6 +646,315 @@ async function geminiGenerateContentAdapter(input) {
646
646
  return output;
647
647
  }
648
648
 
649
+ //#endregion
650
+ //#region src/adapters/kling-video-generations.ts
651
+ const REQUEST_TIMEOUT_MS$3 = 6e4;
652
+ const DEFAULT_POLL_INTERVAL_SEC$1 = 5;
653
+ const DEFAULT_MAX_WAIT_SEC$1 = 900;
654
+ const KLING_MODELS = {
655
+ "kling-text-to-video": {
656
+ submitPath: "/kling/v1/videos/text2video",
657
+ defaultModelName: "kling-v3",
658
+ imageMode: "none"
659
+ },
660
+ "kling-image-to-video": {
661
+ submitPath: "/kling/v1/videos/image2video",
662
+ defaultModelName: "kling-v3",
663
+ imageMode: "single"
664
+ },
665
+ "kling-omni-video": {
666
+ submitPath: "/kling/v1/videos/omni-video",
667
+ defaultModelName: "kling-v3-omni",
668
+ imageMode: "omni",
669
+ allowPromptlessOmni: true
670
+ },
671
+ "kling-multi-image-to-video": {
672
+ submitPath: "/kling/v1/videos/multi-image2video",
673
+ defaultModelName: "kling-v1-6",
674
+ imageMode: "multi"
675
+ }
676
+ };
677
+ function sleep$1(ms) {
678
+ return new Promise((resolve) => setTimeout(resolve, ms));
679
+ }
680
+ function asString$1(value) {
681
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
682
+ }
683
+ function asInteger$1(value, fallback) {
684
+ return typeof value === "number" && Number.isInteger(value) ? value : fallback;
685
+ }
686
+ function asNumber(value) {
687
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
688
+ }
689
+ function isRecord$2(value) {
690
+ return !!value && typeof value === "object" && !Array.isArray(value);
691
+ }
692
+ function providerMeta(input) {
693
+ const rest = { ...input };
694
+ delete rest.cohub;
695
+ delete rest.role;
696
+ return rest;
697
+ }
698
+ function normalizeStatus$1(value) {
699
+ const status = String(value ?? "").trim().toLowerCase();
700
+ if (status === "success" || status === "succeed" || status === "succeeded" || status === "completed") return "succeeded";
701
+ if (status === "queued" || status === "processing" || status === "in_progress" || status === "not_start" || status === "submitted") return "processing";
702
+ if (status === "failure" || status === "failed" || status === "error") return "failed";
703
+ if (status === "cancelled" || status === "canceled") return "cancelled";
704
+ return status || "unknown";
705
+ }
706
+ function getImageRole(block) {
707
+ const role = getBlockMeta(block)?.role;
708
+ return typeof role === "string" && role.trim() ? role.trim() : void 0;
709
+ }
710
+ async function resolveKlingImageSource(input, source) {
711
+ if (source.type === "base64") return source.data;
712
+ return input.context.resolveSource(source);
713
+ }
714
+ async function resolveImages(input) {
715
+ const imageBlocks = input.request.content.filter((block) => block.type === "image");
716
+ return Promise.all(imageBlocks.map(async (block) => {
717
+ const role = getImageRole(block);
718
+ const url = await resolveKlingImageSource(input, block.source);
719
+ return role ? {
720
+ url,
721
+ role
722
+ } : { url };
723
+ }));
724
+ }
725
+ function hasOfficialOmniMedia(meta) {
726
+ return [
727
+ "image_list",
728
+ "element_list",
729
+ "video_list"
730
+ ].some((key) => {
731
+ const value = meta[key];
732
+ return Array.isArray(value) ? value.length > 0 : value !== void 0;
733
+ });
734
+ }
735
+ function hasPlainImagePayload(meta) {
736
+ return typeof meta.image === "string" && meta.image.trim().length > 0;
737
+ }
738
+ function hasMultiImagePayload(meta) {
739
+ return Array.isArray(meta.image_list) && meta.image_list.length > 0;
740
+ }
741
+ function hasPromptlessOmniPayload(meta, images) {
742
+ return images.length > 0 || hasOfficialOmniMedia(meta) || hasPlainImagePayload(meta);
743
+ }
744
+ function omniImageType(image, index) {
745
+ if (image.role === "first_frame" || image.role === "end_frame") return image.role;
746
+ if (image.role === "last_frame") return "end_frame";
747
+ if (!image.role) return index === 0 ? "first_frame" : "end_frame";
748
+ }
749
+ function buildOmniImageList(images) {
750
+ return images.map((image, index) => {
751
+ const type = omniImageType(image, index);
752
+ return type ? {
753
+ image_url: image.url,
754
+ type
755
+ } : { image_url: image.url };
756
+ });
757
+ }
758
+ function buildMultiImageList(images) {
759
+ return images.map((image) => ({ image: image.url }));
760
+ }
761
+ function resolveKlingModel(input) {
762
+ const model = KLING_MODELS[input.declaration.model];
763
+ if (!model) throw new GenerationValidationError(`Unsupported Kling generation model: ${input.declaration.model}`);
764
+ return model;
765
+ }
766
+ function buildPayload$1(input, model, prompt, images) {
767
+ const payload = {
768
+ ...providerMeta(input.meta),
769
+ model_name: model.defaultModelName
770
+ };
771
+ if (prompt) payload.prompt = prompt;
772
+ if (!payload.duration) payload.duration = String(asInteger$1(input.parameters.duration, 5));
773
+ if (!payload.mode) payload.mode = asString$1(input.parameters.mode) ?? "std";
774
+ if (payload.cfg_scale === void 0) payload.cfg_scale = asNumber(input.parameters.cfg_scale) ?? .5;
775
+ if (!payload.aspect_ratio) payload.aspect_ratio = asString$1(input.parameters.aspect_ratio) ?? "16:9";
776
+ if (payload.negative_prompt === void 0 && asString$1(input.parameters.negative_prompt)) payload.negative_prompt = input.parameters.negative_prompt;
777
+ if (payload.sound === void 0 && asString$1(input.parameters.sound)) payload.sound = input.parameters.sound;
778
+ if (model.imageMode === "single" && images[0] && !hasPlainImagePayload(payload)) {
779
+ payload.image = images[0].url;
780
+ if (images[1] && payload.image_tail === void 0) payload.image_tail = images[1].url;
781
+ }
782
+ if (model.imageMode === "omni" && images.length > 0 && !hasOfficialOmniMedia(payload) && !hasPlainImagePayload(payload)) payload.image_list = buildOmniImageList(images);
783
+ if (model.imageMode === "multi" && images.length > 0 && !hasMultiImagePayload(payload)) payload.image_list = buildMultiImageList(images);
784
+ if (payload.seed === void 0 && input.parameters.seed !== void 0) payload.seed = input.parameters.seed;
785
+ return payload;
786
+ }
787
+ function extractTaskId$1(response) {
788
+ const taskId = asString$1(response.task_id) ?? asString$1(response.id) ?? asString$1(response.data?.task_id) ?? asString$1(response.data?.id);
789
+ if (!taskId) throw new GenerationProviderError("Kling video provider did not return a task id", { details: { response } });
790
+ return taskId;
791
+ }
792
+ function extractStatus(response) {
793
+ const wrapper = response.data;
794
+ const native = wrapper?.data;
795
+ const status = normalizeStatus$1(native?.status ?? wrapper?.task_status ?? wrapper?.status ?? response.task_status ?? response.status);
796
+ const firstVideo = wrapper?.task_result?.videos?.[0] ?? native?.task_result?.videos?.[0];
797
+ const videoUrl = asString$1(firstVideo?.url) ?? asString$1(wrapper?.result_url) ?? asString$1(wrapper?.video_url) ?? asString$1(wrapper?.url) ?? asString$1(native?.content?.video_url) ?? asString$1(response.metadata?.url) ?? asString$1(response.result_url) ?? asString$1(response.video_url) ?? asString$1(response.url);
798
+ const message = asString$1(wrapper?.task_status_msg) ?? asString$1(response.error?.message) ?? asString$1(response.message);
799
+ return {
800
+ status,
801
+ videoUrl,
802
+ message,
803
+ metadata: compactObject({
804
+ progress: wrapper?.progress ?? native?.progress ?? response.progress,
805
+ duration: firstVideo?.duration,
806
+ task_status_msg: message,
807
+ code: response.code
808
+ })
809
+ };
810
+ }
811
+ async function requestJson$1(input, path, init) {
812
+ const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, path), {
813
+ ...init,
814
+ headers: {
815
+ Authorization: `Bearer ${input.context.apiKey}`,
816
+ "Content-Type": "application/json",
817
+ ...init.headers
818
+ }
819
+ }, REQUEST_TIMEOUT_MS$3);
820
+ const body = await response.text();
821
+ let parsed = {};
822
+ try {
823
+ parsed = body ? JSON.parse(body) : {};
824
+ } catch {
825
+ throw new GenerationProviderError("Kling video provider returned invalid JSON", {
826
+ status: response.status,
827
+ body
828
+ });
829
+ }
830
+ if (!response.ok) {
831
+ const details = isRecord$2(parsed) ? { details: parsed } : {};
832
+ throw new GenerationProviderError("Kling video provider request failed", {
833
+ status: response.status,
834
+ body,
835
+ ...details
836
+ });
837
+ }
838
+ return parsed;
839
+ }
840
+ async function klingVideoGenerationsAdapter(input) {
841
+ const model = resolveKlingModel(input);
842
+ const prompt = mergeTextBlocks(input.declaration, input.request.content);
843
+ const images = await resolveImages(input);
844
+ const meta = providerMeta(input.meta);
845
+ if (!prompt && !model.allowPromptlessOmni) throw new GenerationValidationError("Prompt text is required");
846
+ if (!prompt && model.allowPromptlessOmni && !hasPromptlessOmniPayload(meta, images)) throw new GenerationValidationError("Prompt text or Omni media input is required");
847
+ if (model.imageMode === "single" && images.length === 0 && !hasPlainImagePayload(meta)) throw new GenerationValidationError("Image input is required");
848
+ if (model.imageMode === "multi" && images.length === 0 && !hasMultiImagePayload(meta)) throw new GenerationValidationError("Multi-image input is required");
849
+ const taskId = extractTaskId$1(await requestJson$1(input, model.submitPath, {
850
+ method: "POST",
851
+ body: JSON.stringify(buildPayload$1(input, model, prompt, images))
852
+ }));
853
+ const pollIntervalSec = asInteger$1(input.parameters.poll_interval, DEFAULT_POLL_INTERVAL_SEC$1);
854
+ const maxWaitSec = asInteger$1(input.parameters.max_wait, DEFAULT_MAX_WAIT_SEC$1);
855
+ const startedAt = Date.now();
856
+ while (Date.now() - startedAt <= maxWaitSec * 1e3) {
857
+ await sleep$1(pollIntervalSec * 1e3);
858
+ const rawStatus = await requestJson$1(input, `${model.submitPath}/${encodeURIComponent(taskId)}`, { method: "GET" });
859
+ const status = extractStatus(rawStatus);
860
+ if (status.status === "succeeded") {
861
+ if (!status.videoUrl) throw new GenerationProviderError("Kling video generation succeeded but returned no video URL", { details: compactObject({
862
+ taskId,
863
+ rawStatus,
864
+ metadata: status.metadata
865
+ }) });
866
+ return [{
867
+ type: "video",
868
+ source: {
869
+ type: "url",
870
+ url: status.videoUrl
871
+ },
872
+ meta: {
873
+ task_id: taskId,
874
+ status: status.status,
875
+ ...status.metadata
876
+ }
877
+ }];
878
+ }
879
+ if (status.status === "failed" || status.status === "cancelled" || status.status === "expired") throw new GenerationProviderError(`Kling video generation ${status.status}`, { details: compactObject({
880
+ taskId,
881
+ message: status.message,
882
+ rawStatus
883
+ }) });
884
+ }
885
+ throw new GenerationTimeoutError("Timed out waiting for Kling video generation", { taskId });
886
+ }
887
+
888
+ //#endregion
889
+ //#region src/adapters/openai-image-edits.ts
890
+ const REQUEST_TIMEOUT_MS$2 = 3e5;
891
+ function firstUrlImage(input) {
892
+ const image = input.request.content.find((block) => block.type === "image");
893
+ if (!image) throw new GenerationValidationError("Source image is required");
894
+ if (image.source.type !== "url") throw new GenerationValidationError("Image edits require an image URL");
895
+ return image.source.url;
896
+ }
897
+ function collectOpenAiImageEditsNoOutputDetails(raw) {
898
+ const data = raw.data ?? [];
899
+ return compactObject({
900
+ created: raw.created,
901
+ usage: raw.usage,
902
+ dataCount: data.length,
903
+ data: compactArray(data.map((item) => compactObject({
904
+ hasUrl: typeof item.url === "string" && item.url.length > 0,
905
+ hasBase64Json: typeof item.b64_json === "string" && item.b64_json.length > 0,
906
+ revisedPrompt: item.revised_prompt
907
+ })))
908
+ });
909
+ }
910
+ async function openAiImageEditsAdapter(input) {
911
+ const prompt = mergeTextBlocks(input.declaration, input.request.content);
912
+ if (!prompt) throw new GenerationValidationError("Edit instruction is required");
913
+ const body = new FormData();
914
+ body.set("model", input.declaration.model);
915
+ body.set("prompt", prompt);
916
+ body.set("image", firstUrlImage(input));
917
+ for (const [key, value] of Object.entries(input.parameters)) if (value !== void 0 && value !== null) body.set(key, String(value));
918
+ const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, "/v1/images/edits"), {
919
+ method: "POST",
920
+ headers: { Authorization: `Bearer ${input.context.apiKey}` },
921
+ body
922
+ }, REQUEST_TIMEOUT_MS$2);
923
+ if (!response.ok) {
924
+ const bodyText = await response.text().catch(() => response.statusText);
925
+ throw new GenerationProviderError("Image edit provider request failed", {
926
+ status: response.status,
927
+ body: bodyText
928
+ });
929
+ }
930
+ const raw = await response.json();
931
+ const output = [];
932
+ for (const item of raw.data ?? []) {
933
+ if (typeof item.url === "string" && item.url) output.push({
934
+ type: "image",
935
+ source: {
936
+ type: "url",
937
+ url: item.url
938
+ }
939
+ });
940
+ if (typeof item.b64_json === "string" && item.b64_json) output.push({
941
+ type: "image",
942
+ source: {
943
+ type: "base64",
944
+ mediaType: "image/png",
945
+ data: item.b64_json
946
+ }
947
+ });
948
+ if (typeof item.revised_prompt === "string" && item.revised_prompt.trim()) output.push({
949
+ type: "text",
950
+ text: item.revised_prompt,
951
+ meta: { role: "revised_prompt" }
952
+ });
953
+ }
954
+ if (output.length === 0) throw new GenerationProviderError("Image edit returned no output", { details: collectOpenAiImageEditsNoOutputDetails(raw) });
955
+ return output;
956
+ }
957
+
649
958
  //#endregion
650
959
  //#region src/adapters/openai-images.ts
651
960
  const REQUEST_TIMEOUT_MS$1 = 3e5;
@@ -666,9 +975,13 @@ function collectOpenAiImagesNoOutputDetails(raw) {
666
975
  })))
667
976
  });
668
977
  }
978
+ function requiresPrompt(input) {
979
+ const textSpec = input.declaration.content.input.find((spec) => spec.type === "text");
980
+ return !!textSpec && (textSpec.required === true || (textSpec.min ?? 0) > 0);
981
+ }
669
982
  async function openAiImagesAdapter(input) {
670
983
  const prompt = mergeTextBlocks(input.declaration, input.request.content);
671
- if (!prompt) throw new GenerationValidationError("Prompt text is required");
984
+ if (!prompt && requiresPrompt(input)) throw new GenerationValidationError("Prompt text is required");
672
985
  const images = await Promise.all(input.request.content.filter((block) => block.type === "image").map((block) => input.context.resolveSource(block.source)));
673
986
  const payload = {
674
987
  model: input.declaration.model,
@@ -724,7 +1037,7 @@ async function openAiImagesAdapter(input) {
724
1037
  const REQUEST_TIMEOUT_MS = 6e4;
725
1038
  const DEFAULT_POLL_INTERVAL_SEC = 5;
726
1039
  const DEFAULT_MAX_WAIT_SEC = 600;
727
- const DEFAULT_MUSIC_VERSION = "chirp-v5-5";
1040
+ const DEFAULT_MUSIC_VERSION = "chirp-v5";
728
1041
  const OPERATION_PATHS = {
729
1042
  music: {
730
1043
  path: "/suno/submit/music",
@@ -778,6 +1091,9 @@ function asString(value) {
778
1091
  function asInteger(value, fallback) {
779
1092
  return typeof value === "number" && Number.isInteger(value) ? value : fallback;
780
1093
  }
1094
+ function asRecord(value) {
1095
+ return isRecord$1(value) ? value : {};
1096
+ }
781
1097
  function successCode(value) {
782
1098
  const code = String(value ?? "").trim().toLowerCase();
783
1099
  return code === "success" || code === "200" || code === "0";
@@ -803,12 +1119,24 @@ function extractTaskId(value) {
803
1119
  }
804
1120
  }
805
1121
  function normalizeStatus(value) {
806
- return String(value ?? "").trim().toLowerCase();
1122
+ const status = String(value ?? "").trim().toLowerCase();
1123
+ if (status === "finished") return "success";
1124
+ if (status === "fail" || status === "rejected") return "failed";
1125
+ return status;
807
1126
  }
808
1127
  function normalizeTask(operation, data) {
809
1128
  if (Array.isArray(data)) return data.length > 0 ? normalizeTask(operation, data[0]) : null;
810
1129
  if (!isRecord$1(data)) return null;
811
- if ("status" in data || "task_id" in data) return data;
1130
+ if ("status" in data || "taskStatus" in data || "task_status" in data || "task_id" in data || "taskBatchId" in data) {
1131
+ const hasProviderEnvelope = "taskStatus" in data || "task_status" in data || "taskBatchId" in data || "task_batch_id" in data;
1132
+ return {
1133
+ ...data,
1134
+ task_id: data.task_id ?? data.taskBatchId ?? data.task_batch_id,
1135
+ status: data.status ?? data.taskStatus ?? data.task_status,
1136
+ fail_reason: data.fail_reason ?? data.failReason,
1137
+ data: data.data ?? (hasProviderEnvelope ? data : void 0)
1138
+ };
1139
+ }
812
1140
  if (Array.isArray(data.data) && data.data.length > 0) return normalizeTask(operation, data.data[0]);
813
1141
  return {
814
1142
  action: operation,
@@ -817,27 +1145,62 @@ function normalizeTask(operation, data) {
817
1145
  };
818
1146
  }
819
1147
  function getOperation(input) {
820
- const operation = asString(input.parameters.operation) ?? "music";
1148
+ const fixedOperation = asString(input.declaration.adapter.operation);
1149
+ const requestedOperation = asString(input.parameters.operation);
1150
+ if (fixedOperation && requestedOperation && fixedOperation !== requestedOperation) throw new GenerationValidationError(`${input.declaration.model} uses Suno operation ${fixedOperation}; parameters.operation cannot override it`);
1151
+ const operation = fixedOperation ?? requestedOperation ?? "music";
821
1152
  if (!OPERATION_PATHS[operation]) throw new GenerationValidationError(`Unsupported Suno operation: ${operation}`);
822
1153
  return operation;
823
1154
  }
824
1155
  async function buildPayload(input, operation) {
825
- const payload = { ...input.meta };
1156
+ const payload = {
1157
+ ...asRecord(input.declaration.adapter.defaults),
1158
+ ...input.meta
1159
+ };
826
1160
  const config = OPERATION_PATHS[operation];
827
1161
  const prompt = mergeTextBlocks(input.declaration, input.request.content);
828
1162
  if (prompt && config?.textField && payload[config.textField] === void 0) payload[config.textField] = prompt;
829
- if (config?.textField && config.textField !== "prompt" && payload[config.textField] === void 0 && payload.prompt !== void 0) payload[config.textField] = payload.prompt;
830
1163
  const audioBlock = input.request.content.find((block) => block.type === "audio");
831
1164
  if (audioBlock && payload.url === void 0) payload.url = await input.context.resolveSource(audioBlock.source);
832
1165
  const imageBlock = input.request.content.find((block) => block.type === "image");
833
- if (imageBlock && payload.image_url === void 0) payload.image_url = await input.context.resolveSource(imageBlock.source);
1166
+ let imageUrl;
1167
+ if (imageBlock) {
1168
+ imageUrl = await input.context.resolveSource(imageBlock.source);
1169
+ if (payload.image_url === void 0) payload.image_url = imageUrl;
1170
+ }
834
1171
  const videoBlock = input.request.content.find((block) => block.type === "video");
835
- if (videoBlock && payload.video_url === void 0) payload.video_url = await input.context.resolveSource(videoBlock.source);
1172
+ let videoUrl;
1173
+ if (videoBlock) {
1174
+ videoUrl = await input.context.resolveSource(videoBlock.source);
1175
+ if (payload.video_url === void 0) payload.video_url = videoUrl;
1176
+ }
1177
+ applyFixedPayload(input, payload, asRecord(input.declaration.adapter.payload));
1178
+ const fixedTask = asString(input.declaration.adapter.task);
1179
+ if (fixedTask) applyFixedPayload(input, payload, { task: fixedTask });
1180
+ const task = asString(payload.task);
1181
+ if (task === "image_to_song" && imageUrl) setMetadataParam(payload, "image_url", imageUrl);
1182
+ if (task === "video_to_song" && videoUrl) setMetadataParam(payload, "video_url", videoUrl);
1183
+ if (task === "cover" && payload.clip_id === void 0) {
1184
+ const coverClipId = asString(payload.cover_clip_id);
1185
+ if (coverClipId) payload.clip_id = coverClipId;
1186
+ }
836
1187
  normalizeMusicTaskPayload(input, operation, payload);
837
1188
  if (config?.defaultMusicVersion && payload.mv === void 0 && payload.model_name === void 0) payload.mv = DEFAULT_MUSIC_VERSION;
838
1189
  validateSunoPayload(operation, payload);
839
1190
  return payload;
840
1191
  }
1192
+ function applyFixedPayload(input, payload, fixed) {
1193
+ for (const [key, value] of Object.entries(fixed)) {
1194
+ if (value === void 0) continue;
1195
+ if (payload[key] !== void 0 && payload[key] !== value) throw new GenerationValidationError(`${input.declaration.model} fixes Suno ${key}; meta.${key} cannot override it`);
1196
+ payload[key] = value;
1197
+ }
1198
+ }
1199
+ function setMetadataParam(payload, key, value) {
1200
+ const metadataParams = isRecord$1(payload.metadata_params) ? payload.metadata_params : {};
1201
+ if (metadataParams[key] === void 0) metadataParams[key] = value;
1202
+ payload.metadata_params = metadataParams;
1203
+ }
841
1204
  function contentCount(content, type) {
842
1205
  return content.filter((block) => block.type === type).length;
843
1206
  }
@@ -1033,6 +1396,8 @@ async function sunoTasksAdapter(input) {
1033
1396
  const builtinGenerationAdapters = {
1034
1397
  "ark.videoGenerations": arkVideoGenerationsAdapter,
1035
1398
  "gemini.generateContent": geminiGenerateContentAdapter,
1399
+ "kling.videoGenerations": klingVideoGenerationsAdapter,
1400
+ "openai.imageEdits": openAiImageEditsAdapter,
1036
1401
  "openai.images": openAiImagesAdapter,
1037
1402
  "suno.tasks": sunoTasksAdapter
1038
1403
  };
@@ -1127,12 +1492,46 @@ const defaultGenerationSourceResolver = (source) => {
1127
1492
  //#endregion
1128
1493
  //#region src/client.ts
1129
1494
  const DEFAULT_BASE_URL = "https://router.neta.art";
1130
- function redactDebugEvent(value) {
1131
- if (Array.isArray(value)) return value.map((item) => redactDebugEvent(item));
1495
+ const REDACTED = "[REDACTED]";
1496
+ const SECRET_DEBUG_KEY_PATTERN = /^(authorization|api[-_]?key|token|thoughtSignature)$/i;
1497
+ const BASE64_DEBUG_KEY_PATTERN = /^(b64_json|data)$/i;
1498
+ const MEDIA_PAYLOAD_KEYS = new Set([
1499
+ "audio",
1500
+ "audio_url",
1501
+ "image",
1502
+ "image_tail",
1503
+ "image_url",
1504
+ "first_frame",
1505
+ "mask",
1506
+ "result_url",
1507
+ "static_mask",
1508
+ "url",
1509
+ "video",
1510
+ "video_url",
1511
+ "watermark_url"
1512
+ ]);
1513
+ function isUrlLike(value) {
1514
+ return /^(https?:|s3:|gs:|file:|blob:)\/\//i.test(value.trim());
1515
+ }
1516
+ function isBase64Like(value) {
1517
+ const compact = value.trim().replace(/\s/g, "");
1518
+ if (compact.length < 256 || compact.length % 4 === 1) return false;
1519
+ return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(compact);
1520
+ }
1521
+ function shouldRedactString(key, value) {
1522
+ const trimmed = value.trim();
1523
+ if (!trimmed) return false;
1524
+ if (/^data:/i.test(trimmed)) return true;
1525
+ if (isBase64Like(trimmed)) return true;
1526
+ return !!key && MEDIA_PAYLOAD_KEYS.has(key.toLowerCase()) && !isUrlLike(trimmed);
1527
+ }
1528
+ function redactDebugEvent(value, options, key) {
1529
+ if (typeof value === "string") return shouldRedactString(key, value) ? REDACTED : value;
1530
+ if (Array.isArray(value)) return value.map((item) => redactDebugEvent(item, options, key));
1132
1531
  if (!value || typeof value !== "object") return value;
1133
1532
  const output = {};
1134
- for (const [key, child] of Object.entries(value)) if (/^(authorization|api[-_]?key|token|b64_json|thoughtSignature)$/i.test(key) || key === "data") output[key] = "[REDACTED]";
1135
- else output[key] = redactDebugEvent(child);
1533
+ for (const [childKey, child] of Object.entries(value)) if (BASE64_DEBUG_KEY_PATTERN.test(childKey) || options.redactSecrets && SECRET_DEBUG_KEY_PATTERN.test(childKey)) output[childKey] = REDACTED;
1534
+ else output[childKey] = redactDebugEvent(child, options, childKey);
1136
1535
  return output;
1137
1536
  }
1138
1537
  function defaultDebugLogger(event) {
@@ -1144,7 +1543,7 @@ function resolveDebugConfig(debug) {
1144
1543
  enabled: true,
1145
1544
  includeSensitive: false,
1146
1545
  includeResponseBody: true,
1147
- logger: (event) => defaultDebugLogger(redactDebugEvent(event))
1546
+ logger: (event) => defaultDebugLogger(redactDebugEvent(event, { redactSecrets: true }))
1148
1547
  };
1149
1548
  if (!debug.enabled) return void 0;
1150
1549
  const includeSensitive = debug.includeSensitive ?? false;
@@ -1153,7 +1552,7 @@ function resolveDebugConfig(debug) {
1153
1552
  enabled: true,
1154
1553
  includeSensitive,
1155
1554
  includeResponseBody: debug.includeResponseBody ?? true,
1156
- logger: (event) => logger(includeSensitive ? event : redactDebugEvent(event))
1555
+ logger: (event) => logger(redactDebugEvent(event, { redactSecrets: !includeSensitive }))
1157
1556
  };
1158
1557
  }
1159
1558
  function resolveModels(options) {
@@ -1259,5 +1658,5 @@ async function exportBuiltinModelConfigs(directory) {
1259
1658
  }
1260
1659
 
1261
1660
  //#endregion
1262
- export { GenerationError as A, arkVideoGenerationsAdapter as C, resolveGenerationParameters as D, resolveGenerationMeta as E, GenerationTimeoutError as M, GenerationUnsupportedAdapterError as N, validateGenerationContent as O, GenerationValidationError as P, geminiGenerateContentAdapter as S, mergeTextBlocks 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, GenerationProviderError as j, GenerationConfigError 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, mergeGenerationMeta as w, openAiImagesAdapter as x, getGenerationAdapter as y };
1263
- //# sourceMappingURL=export-config-D8By2_r7.js.map
1661
+ 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 };
1662
+ //# sourceMappingURL=export-config-DS2XD-tF.js.map