@shop-os/modelkit 0.2.9 → 0.2.10

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/dist/index.cjs CHANGED
@@ -1569,6 +1569,7 @@ var VIDEO_MODELS = [
1569
1569
  },
1570
1570
  {
1571
1571
  // generateAudio defaults to false here (trigger-workflows); Space Builder defaults it to true.
1572
+ // omni_reference_task_type edit/extend: adaptive ratio, edit sends duration -1.
1572
1573
  id: "seedance-2.5",
1573
1574
  aliases: ["seedance-2-5", "dreamina-seedance-2-5-260628"],
1574
1575
  label: "Seedance 2.5",
@@ -1583,7 +1584,7 @@ var VIDEO_MODELS = [
1583
1584
  durations: { min: 4, max: 30 },
1584
1585
  references: { images: 30, videos: 10, audios: 10 },
1585
1586
  ratioIgnoredWith: ["firstFrame", "sourceVideo"],
1586
- supports: ["generateAudio", "seed", "lastFrame", "watermark"]
1587
+ supports: ["generateAudio", "seed", "lastFrame", "watermark", "taskType"]
1587
1588
  },
1588
1589
  defaults: {
1589
1590
  durationSeconds: 5,
@@ -1692,6 +1693,9 @@ var VIDEO_MODELS = [
1692
1693
  },
1693
1694
  {
1694
1695
  // mode standard/pro selects 720p/1080p; the endpoint takes no separate resolution.
1696
+ // Replicate: "Max 7 [images] without video, 4 with video"; 4K does not support
1697
+ // reference_video. No `videos` limit yet: the adapter sends no reference video,
1698
+ // so `imagesWithVideo` stays dormant until one is wired through.
1695
1699
  id: "kling-v3-omni-video",
1696
1700
  aliases: ["kwaivgi/kling-v3-omni-video", "kling-v3-omni"],
1697
1701
  label: "Kling V3 Omni",
@@ -1704,7 +1708,7 @@ var VIDEO_MODELS = [
1704
1708
  aspectRatios: [...KLING_RATIOS],
1705
1709
  resolutions: ["720p", "1080p"],
1706
1710
  durations: { min: 3, max: 15 },
1707
- references: { images: 7 },
1711
+ references: { images: 7, imagesWithVideo: 4 },
1708
1712
  supports: ["generateAudio", "lastFrame"]
1709
1713
  },
1710
1714
  defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
@@ -1980,6 +1984,7 @@ var SupportedOptionSchema = import_zod.z.enum([
1980
1984
  "upscale",
1981
1985
  "watermark",
1982
1986
  "safetyChecker",
1987
+ "taskType",
1983
1988
  "instrumental"
1984
1989
  ]);
1985
1990
  var UsageUnitSchema = import_zod.z.enum([
@@ -2002,6 +2007,7 @@ var ProviderOptionValueSchema = import_zod.z.lazy(
2002
2007
  var ProviderOptionsSchema = import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), ProviderOptionValueSchema));
2003
2008
  var ReferenceLimitsSchema = import_zod.z.looseObject({
2004
2009
  images: import_zod.z.number().optional(),
2010
+ imagesWithVideo: import_zod.z.number().optional(),
2005
2011
  videos: import_zod.z.number().optional(),
2006
2012
  audios: import_zod.z.number().optional(),
2007
2013
  total: import_zod.z.number().optional(),
@@ -2063,6 +2069,7 @@ var DefaultsSchema = import_zod.z.looseObject({
2063
2069
  promptExpansion: import_zod.z.enum(["fast", "balanced", "quality"]).optional(),
2064
2070
  watermark: import_zod.z.boolean().optional(),
2065
2071
  safetyChecker: import_zod.z.boolean().optional(),
2072
+ taskType: import_zod.z.enum(["reference", "edit", "extend"]).optional(),
2066
2073
  mode: import_zod.z.enum(["standard", "pro"]).optional(),
2067
2074
  instrumental: import_zod.z.boolean().optional()
2068
2075
  });
@@ -2622,6 +2629,9 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
2622
2629
  model,
2623
2630
  warnings
2624
2631
  );
2632
+ if (limits.imagesWithVideo !== void 0 && (limits.videos ?? 0) > 0 && videos.length > 0 && images.length > limits.imagesWithVideo) {
2633
+ images = trim("referenceImages", images, limits.imagesWithVideo, model, warnings);
2634
+ }
2625
2635
  if (limits.total !== void 0) {
2626
2636
  let over = images.length + videos.length + audios.length - limits.total;
2627
2637
  if (over > 0) {
@@ -2655,7 +2665,8 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
2655
2665
  "promptExpansion",
2656
2666
  "lastFrame",
2657
2667
  "watermark",
2658
- "safetyChecker"
2668
+ "safetyChecker",
2669
+ "taskType"
2659
2670
  ]);
2660
2671
  return { request: merged, warnings };
2661
2672
  }
@@ -4096,9 +4107,22 @@ function seedanceErrorMessage(error, status) {
4096
4107
  return `Seedance task ${status}`;
4097
4108
  }
4098
4109
  async function generateSeedanceVideo(req, ctx) {
4099
- const key = arkKey(ctx);
4100
4110
  const modelId = ctx.model.id;
4101
- const duration = req.durationSeconds ?? 5;
4111
+ const taskType = req.taskType;
4112
+ const hasVideo = Boolean(req.sourceVideo) || (req.referenceVideos?.length ?? 0) > 0;
4113
+ if ((taskType === "edit" || taskType === "extend") && !hasVideo) {
4114
+ throw new ModelKitError({
4115
+ code: "missing_input",
4116
+ message: `${ctx.model.id} ${taskType} task needs a source or reference video`,
4117
+ provider: "ark",
4118
+ model: ctx.model.id,
4119
+ retryable: false
4120
+ });
4121
+ }
4122
+ const key = arkKey(ctx);
4123
+ const requestedDuration = req.durationSeconds ?? 5;
4124
+ let duration = requestedDuration;
4125
+ if (taskType === "edit") duration = -1;
4102
4126
  const resolution = req.resolution ?? "720p";
4103
4127
  const content = [{ type: "text", text: req.prompt }];
4104
4128
  if (req.firstFrame) {
@@ -4150,7 +4174,10 @@ async function generateSeedanceVideo(req, ctx) {
4150
4174
  duration,
4151
4175
  resolution
4152
4176
  };
4153
- if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
4177
+ if (taskType === "edit" || taskType === "extend") body.ratio = "adaptive";
4178
+ else if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
4179
+ if (taskType !== void 0 && ctx.model.id === "seedance-2.5")
4180
+ body.omni_reference_task_type = taskType;
4154
4181
  if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
4155
4182
  if (req.seed !== void 0) body.seed = req.seed;
4156
4183
  if (req.watermark !== void 0) body.watermark = req.watermark;
@@ -4170,7 +4197,7 @@ async function generateSeedanceVideo(req, ctx) {
4170
4197
  }, retryOptsFor(ctx));
4171
4198
  if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
4172
4199
  const jobId = submit.id;
4173
- const usage2 = seedanceUsage(ctx, req, duration);
4200
+ const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
4174
4201
  const fetchStatus = async () => {
4175
4202
  const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
4176
4203
  headers: { Authorization: `Bearer ${key}` }
@@ -4217,6 +4244,10 @@ async function generateSeedanceVideo(req, ctx) {
4217
4244
  "Seedance task succeeded but returned no video_url",
4218
4245
  modelId
4219
4246
  );
4247
+ if (polled.duration !== void 0 && polled.duration > 0) {
4248
+ usage2.quantity = polled.duration;
4249
+ usage2.durationSeconds = polled.duration;
4250
+ }
4220
4251
  const tokens = polled.usage;
4221
4252
  if (tokens?.total_tokens !== void 0 && tokens.completion_tokens !== void 0) {
4222
4253
  usage2.inputTokens = tokens.total_tokens - tokens.completion_tokens;
@@ -5270,7 +5301,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
5270
5301
  const apiKey = googleKey(ctx);
5271
5302
  const modelId = ctx.model.id;
5272
5303
  const providerModelId = ctx.model.providerModelId;
5273
- const duration = req.durationSeconds ?? 8;
5304
+ const duration = req.durationSeconds ?? 10;
5274
5305
  const images = req.referenceImages ?? [];
5275
5306
  const videos = req.referenceVideos ?? [];
5276
5307
  const task = req.sourceVideo ? "edit" : req.firstFrame ? "image_to_video" : images.length > 0 || videos.length > 0 ? "reference_to_video" : "text_to_video";