@seawork/server 1.0.12 → 1.0.13-rc.2

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 (34) hide show
  1. package/dist/server/server/sac/generate.d.ts.map +1 -1
  2. package/dist/server/server/sac/generate.js.map +1 -1
  3. package/dist/server/server/sac/providers/alibaba.js +231 -249
  4. package/dist/server/server/sac/providers/alibaba.js.map +1 -1
  5. package/dist/server/server/sac/providers/audio.js +16 -19
  6. package/dist/server/server/sac/providers/audio.js.map +1 -1
  7. package/dist/server/server/sac/providers/kling.js +157 -184
  8. package/dist/server/server/sac/providers/kling.js.map +1 -1
  9. package/dist/server/server/sac/providers/nano.js +7 -9
  10. package/dist/server/server/sac/providers/nano.js.map +1 -1
  11. package/dist/server/server/sac/providers/pixverse.js +436 -425
  12. package/dist/server/server/sac/providers/pixverse.js.map +1 -1
  13. package/dist/server/server/sac/providers/seaart.d.ts.map +1 -1
  14. package/dist/server/server/sac/providers/seaart.js +6 -10
  15. package/dist/server/server/sac/providers/seaart.js.map +1 -1
  16. package/dist/server/server/sac/providers/store.d.ts +1 -1
  17. package/dist/server/server/sac/providers/tencent-3d.js +59 -57
  18. package/dist/server/server/sac/providers/tencent-3d.js.map +1 -1
  19. package/dist/server/server/sac/providers/tencent-image.js +39 -38
  20. package/dist/server/server/sac/providers/tencent-image.js.map +1 -1
  21. package/dist/server/server/sac/providers/tencent-video.js +58 -57
  22. package/dist/server/server/sac/providers/tencent-video.js.map +1 -1
  23. package/dist/server/server/sac/providers/tripo3d.js +135 -136
  24. package/dist/server/server/sac/providers/tripo3d.js.map +1 -1
  25. package/dist/server/server/sac/providers/vidu.js +470 -467
  26. package/dist/server/server/sac/providers/vidu.js.map +1 -1
  27. package/dist/server/server/sac/providers/volces-3d.js +30 -32
  28. package/dist/server/server/sac/providers/volces-3d.js.map +1 -1
  29. package/dist/server/server/sac/providers/volces-video.js +87 -83
  30. package/dist/server/server/sac/providers/volces-video.js.map +1 -1
  31. package/dist/server/server/sac/providers/volces.d.ts.map +1 -1
  32. package/dist/server/server/sac/providers/volces.js +44 -42
  33. package/dist/server/server/sac/providers/volces.js.map +1 -1
  34. package/package.json +3 -3
@@ -2,69 +2,44 @@ import { SACError as CLIError, ExitCode } from "../errors.js";
2
2
  import { registerProvider } from "./store.js";
3
3
  // ── Model lists ──────────────────────────────────────────────────────────────
4
4
  const T2V_MODELS = [
5
- 'kling_v1',
6
- 'kling_v1_5',
7
- 'kling_v1_6',
8
- 'kling_v2_master',
9
- 'kling_v2_1_master',
10
- 'kling_v2_5_turbo',
11
- 'kling_v2_6',
12
- 'kling_v3',
5
+ "kling_v1",
6
+ "kling_v1_5",
7
+ "kling_v1_6",
8
+ "kling_v2_master",
9
+ "kling_v2_1_master",
10
+ "kling_v2_5_turbo",
11
+ "kling_v2_6",
12
+ "kling_v3",
13
13
  ];
14
14
  const I2V_MODELS = [
15
- 'kling_v1_i2v',
16
- 'kling_v1_5_i2v',
17
- 'kling_v1_6_i2v',
18
- 'kling_v2_1_i2v',
19
- 'kling_v2_master_i2v',
20
- 'kling_v2_1_master_i2v',
21
- 'kling_v2_5_turbo_i2v',
22
- 'kling_v2_6_i2v',
23
- 'kling_v3_i2v',
24
- ];
25
- const IMAGE_V3_MODELS = [
26
- 'kling_v3_image',
27
- ];
28
- const OMNI_IMAGE_MODELS = [
29
- 'kling_omni_image',
30
- 'kling_v3_omni_image',
31
- ];
32
- const AVATAR_MODELS = [
33
- 'kling_avatar',
34
- ];
35
- const EFFECTS_SINGLE_MODELS = [
36
- 'kling_effects_single',
15
+ "kling_v1_i2v",
16
+ "kling_v1_5_i2v",
17
+ "kling_v1_6_i2v",
18
+ "kling_v2_1_i2v",
19
+ "kling_v2_master_i2v",
20
+ "kling_v2_1_master_i2v",
21
+ "kling_v2_5_turbo_i2v",
22
+ "kling_v2_6_i2v",
23
+ "kling_v3_i2v",
37
24
  ];
25
+ const IMAGE_V3_MODELS = ["kling_v3_image"];
26
+ const OMNI_IMAGE_MODELS = ["kling_omni_image", "kling_v3_omni_image"];
27
+ const AVATAR_MODELS = ["kling_avatar"];
28
+ const EFFECTS_SINGLE_MODELS = ["kling_effects_single"];
38
29
  const EFFECTS_MULTI_MODELS = [
39
- 'kling_effects_multi_v1',
40
- 'kling_effects_multi_v15',
41
- 'kling_effects_multi_v16',
42
- ];
43
- const MOTION_CONTROL_MODELS = [
44
- 'kling_motion_control',
45
- 'kling_v3_motion_control',
46
- ];
47
- const DURATION_EXTENSION_MODELS = [
48
- 'kling_duration_extension',
49
- ];
50
- const LIPSYNC_MODELS = [
51
- 'kling_lipsync',
52
- ];
53
- const OMNI_VIDEO_MODELS = [
54
- 'kling_omni_video',
55
- 'kling_v3_omni_video',
56
- ];
57
- const VIDEO_TO_AUDIO_MODELS = [
58
- 'kling_video_to_audio',
59
- ];
60
- const TENCENT_KLING_I2V_MODELS = [
61
- 'tencent_kling_v3',
62
- ];
63
- const TENCENT_KLING_OMNI_VIDEO_MODELS = [
64
- 'tencent_kling_v3_omni',
30
+ "kling_effects_multi_v1",
31
+ "kling_effects_multi_v15",
32
+ "kling_effects_multi_v16",
65
33
  ];
34
+ const MOTION_CONTROL_MODELS = ["kling_motion_control", "kling_v3_motion_control"];
35
+ const DURATION_EXTENSION_MODELS = ["kling_duration_extension"];
36
+ const LIPSYNC_MODELS = ["kling_lipsync"];
37
+ const OMNI_VIDEO_MODELS = ["kling_omni_video", "kling_v3_omni_video"];
38
+ const VIDEO_TO_AUDIO_MODELS = ["kling_video_to_audio"];
39
+ const TENCENT_KLING_I2V_MODELS = ["tencent_kling_v3"];
40
+ const TENCENT_KLING_OMNI_VIDEO_MODELS = ["tencent_kling_v3_omni"];
66
41
  const T2V_SET = new Set(T2V_MODELS);
67
- const VIDEO_REFER_TYPES = new Set(['feature', 'base']);
42
+ const VIDEO_REFER_TYPES = new Set(["feature", "base"]);
68
43
  function buildEnvelope(model, params) {
69
44
  return {
70
45
  model,
@@ -75,13 +50,13 @@ function buildEnvelope(model, params) {
75
50
  };
76
51
  }
77
52
  function requireStringFlag(value, message) {
78
- if (typeof value !== 'string' || value.length === 0) {
53
+ if (typeof value !== "string" || value.length === 0) {
79
54
  throw new CLIError(message, ExitCode.USAGE);
80
55
  }
81
56
  return value;
82
57
  }
83
58
  function requireNumberFlag(value, message) {
84
- if (typeof value !== 'number' || Number.isNaN(value)) {
59
+ if (typeof value !== "number" || Number.isNaN(value)) {
85
60
  throw new CLIError(message, ExitCode.USAGE);
86
61
  }
87
62
  return value;
@@ -89,21 +64,21 @@ function requireNumberFlag(value, message) {
89
64
  function parseEnum(model, value, flagName, allowed) {
90
65
  if (value === undefined)
91
66
  return undefined;
92
- if (typeof value !== 'string' || !allowed.has(value)) {
93
- throw new CLIError(`Model "${model}" requires --${flagName} to be one of: ${Array.from(allowed).join(', ')}.`, ExitCode.USAGE);
67
+ if (typeof value !== "string" || !allowed.has(value)) {
68
+ throw new CLIError(`Model "${model}" requires --${flagName} to be one of: ${Array.from(allowed).join(", ")}.`, ExitCode.USAGE);
94
69
  }
95
70
  return value;
96
71
  }
97
72
  function maybeStringArray(value) {
98
73
  if (Array.isArray(value))
99
- return value.filter((item) => typeof item === 'string' && item.length > 0);
100
- if (typeof value === 'string' && value.length > 0)
74
+ return value.filter((item) => typeof item === "string" && item.length > 0);
75
+ if (typeof value === "string" && value.length > 0)
101
76
  return [value];
102
77
  return [];
103
78
  }
104
79
  function collectImageInputs(flags) {
105
80
  const images = maybeStringArray(flags.imageUrls);
106
- if (typeof flags.imageUrl === 'string' && flags.imageUrl.length > 0) {
81
+ if (typeof flags.imageUrl === "string" && flags.imageUrl.length > 0) {
107
82
  return [flags.imageUrl, ...images];
108
83
  }
109
84
  return images;
@@ -115,23 +90,25 @@ function buildElementList(flags) {
115
90
  return collectElementIds(flags).map((elementId) => ({ element_id: elementId }));
116
91
  }
117
92
  function requireVideoSource(model, flags, options = {}) {
118
- const videoId = typeof flags.videoId === 'string' && flags.videoId.length > 0 ? flags.videoId : undefined;
119
- const videoUrl = typeof flags.videoUrl === 'string' && flags.videoUrl.length > 0 ? flags.videoUrl : undefined;
93
+ const videoId = typeof flags.videoId === "string" && flags.videoId.length > 0 ? flags.videoId : undefined;
94
+ const videoUrl = typeof flags.videoUrl === "string" && flags.videoUrl.length > 0 ? flags.videoUrl : undefined;
120
95
  if (!options.allowBoth && videoId && videoUrl) {
121
96
  throw new CLIError(`Model "${model}" accepts either --video-id or --video-url, not both.`, ExitCode.USAGE);
122
97
  }
123
98
  if (videoId)
124
- return { key: 'video_id', value: videoId };
99
+ return { key: "video_id", value: videoId };
125
100
  if (videoUrl)
126
- return { key: 'video_url', value: videoUrl };
101
+ return { key: "video_url", value: videoUrl };
127
102
  throw new CLIError(`Model "${model}" requires --video-id or --video-url.`, ExitCode.USAGE);
128
103
  }
129
104
  function buildOmniImageList(flags) {
130
105
  return collectImageInputs(flags).map((image) => ({ image }));
131
106
  }
132
107
  function buildOmniVideoImageList(model, flags) {
133
- const imageUrl = typeof flags.imageUrl === 'string' && flags.imageUrl.length > 0 ? flags.imageUrl : undefined;
134
- const imageTailUrl = typeof flags.imageTailUrl === 'string' && flags.imageTailUrl.length > 0 ? flags.imageTailUrl : undefined;
108
+ const imageUrl = typeof flags.imageUrl === "string" && flags.imageUrl.length > 0 ? flags.imageUrl : undefined;
109
+ const imageTailUrl = typeof flags.imageTailUrl === "string" && flags.imageTailUrl.length > 0
110
+ ? flags.imageTailUrl
111
+ : undefined;
135
112
  const imageUrls = maybeStringArray(flags.imageUrls);
136
113
  if (imageTailUrl && !imageUrl) {
137
114
  throw new CLIError(`Model "${model}" requires --image-url when using --image-tail-url.`, ExitCode.USAGE);
@@ -141,43 +118,43 @@ function buildOmniVideoImageList(model, flags) {
141
118
  }
142
119
  const list = [];
143
120
  if (imageUrl)
144
- list.push({ image_url: imageUrl, type: 'first_frame' });
121
+ list.push({ image_url: imageUrl, type: "first_frame" });
145
122
  if (imageTailUrl)
146
- list.push({ image_url: imageTailUrl, type: 'end_frame' });
123
+ list.push({ image_url: imageTailUrl, type: "end_frame" });
147
124
  for (const image of imageUrls)
148
125
  list.push({ image_url: image });
149
126
  return list;
150
127
  }
151
128
  function applyCommonParams(params, flags) {
152
129
  if (flags.duration !== undefined)
153
- params['duration'] = String(flags.duration);
130
+ params["duration"] = String(flags.duration);
154
131
  if (flags.aspectRatio)
155
- params['aspect_ratio'] = flags.aspectRatio;
132
+ params["aspect_ratio"] = flags.aspectRatio;
156
133
  if (flags.mode)
157
- params['mode'] = flags.mode;
134
+ params["mode"] = flags.mode;
158
135
  if (flags.negativePrompt)
159
- params['negative_prompt'] = flags.negativePrompt;
136
+ params["negative_prompt"] = flags.negativePrompt;
160
137
  if (flags.cfgScale !== undefined)
161
- params['cfg_scale'] = flags.cfgScale;
138
+ params["cfg_scale"] = flags.cfgScale;
162
139
  if (flags.sound)
163
- params['sound'] = flags.sound;
140
+ params["sound"] = flags.sound;
164
141
  if (flags.multiShot !== undefined)
165
- params['multi_shot'] = flags.multiShot;
142
+ params["multi_shot"] = flags.multiShot;
166
143
  if (flags.shotType)
167
- params['shot_type'] = flags.shotType;
144
+ params["shot_type"] = flags.shotType;
168
145
  if (flags.watermark !== undefined) {
169
- params['watermark_info'] = { enabled: flags.watermark };
146
+ params["watermark_info"] = { enabled: flags.watermark };
170
147
  }
171
148
  if (flags.externalTaskId)
172
- params['external_task_id'] = flags.externalTaskId;
149
+ params["external_task_id"] = flags.externalTaskId;
173
150
  }
174
151
  function buildOmniVideoParams(model, prompt, flags) {
175
152
  const imageList = buildOmniVideoImageList(model, flags);
176
153
  const elementList = buildElementList(flags);
177
- const hasTypedFrameImages = typeof flags.imageUrl === 'string' || typeof flags.imageTailUrl === 'string';
178
- const videoUrl = typeof flags.videoUrl === 'string' && flags.videoUrl.length > 0 ? flags.videoUrl : undefined;
179
- const videoReferType = parseEnum(model, flags.videoReferType, 'video-refer-type', VIDEO_REFER_TYPES) ?? 'base';
180
- if (videoUrl && videoReferType !== 'feature' && hasTypedFrameImages) {
154
+ const hasTypedFrameImages = typeof flags.imageUrl === "string" || typeof flags.imageTailUrl === "string";
155
+ const videoUrl = typeof flags.videoUrl === "string" && flags.videoUrl.length > 0 ? flags.videoUrl : undefined;
156
+ const videoReferType = parseEnum(model, flags.videoReferType, "video-refer-type", VIDEO_REFER_TYPES) ?? "base";
157
+ if (videoUrl && videoReferType !== "feature" && hasTypedFrameImages) {
181
158
  throw new CLIError(`Model "${model}" does not allow --image-url/--image-tail-url when --video-refer-type is base.`, ExitCode.USAGE);
182
159
  }
183
160
  if (!videoUrl && !hasTypedFrameImages && !flags.aspectRatio) {
@@ -185,32 +162,32 @@ function buildOmniVideoParams(model, prompt, flags) {
185
162
  }
186
163
  const params = { prompt };
187
164
  if (imageList.length > 0)
188
- params['image_list'] = imageList;
165
+ params["image_list"] = imageList;
189
166
  if (videoUrl) {
190
167
  const videoItem = {
191
168
  video_url: videoUrl,
192
169
  refer_type: videoReferType,
193
170
  };
194
171
  if (flags.keepOriginalSound)
195
- videoItem['keep_original_sound'] = flags.keepOriginalSound;
196
- params['video_list'] = [videoItem];
172
+ videoItem["keep_original_sound"] = flags.keepOriginalSound;
173
+ params["video_list"] = [videoItem];
197
174
  }
198
175
  if (elementList.length > 0)
199
- params['element_list'] = elementList;
176
+ params["element_list"] = elementList;
200
177
  if (flags.mode)
201
- params['mode'] = flags.mode;
178
+ params["mode"] = flags.mode;
202
179
  if (flags.aspectRatio)
203
- params['aspect_ratio'] = flags.aspectRatio;
180
+ params["aspect_ratio"] = flags.aspectRatio;
204
181
  if (flags.duration !== undefined)
205
- params['duration'] = String(flags.duration);
182
+ params["duration"] = String(flags.duration);
206
183
  if (flags.externalTaskId)
207
- params['external_task_id'] = flags.externalTaskId;
184
+ params["external_task_id"] = flags.externalTaskId;
208
185
  return params;
209
186
  }
210
187
  // ── Image generation ─────────────────────────────────────────────────────────
211
188
  registerProvider({
212
- provider: 'kling',
213
- category: 'image',
189
+ provider: "kling",
190
+ category: "image",
214
191
  models: IMAGE_V3_MODELS,
215
192
  buildBody(model, prompt, flags) {
216
193
  if (flags.imageUrls) {
@@ -221,64 +198,64 @@ registerProvider({
221
198
  }
222
199
  const params = { prompt };
223
200
  if (flags.negativePrompt)
224
- params['negative_prompt'] = flags.negativePrompt;
201
+ params["negative_prompt"] = flags.negativePrompt;
225
202
  if (flags.imageUrl)
226
- params['image'] = flags.imageUrl;
203
+ params["image"] = flags.imageUrl;
227
204
  const elementList = buildElementList(flags);
228
205
  if (elementList.length > 0)
229
- params['element_list'] = elementList;
206
+ params["element_list"] = elementList;
230
207
  if (flags.resolution)
231
- params['resolution'] = flags.resolution;
208
+ params["resolution"] = flags.resolution;
232
209
  if (flags.n !== undefined)
233
- params['n'] = flags.n;
210
+ params["n"] = flags.n;
234
211
  if (flags.aspectRatio)
235
- params['aspect_ratio'] = flags.aspectRatio;
212
+ params["aspect_ratio"] = flags.aspectRatio;
236
213
  if (flags.watermark !== undefined)
237
- params['watermark_info'] = { enabled: flags.watermark };
214
+ params["watermark_info"] = { enabled: flags.watermark };
238
215
  if (flags.externalTaskId)
239
- params['external_task_id'] = flags.externalTaskId;
216
+ params["external_task_id"] = flags.externalTaskId;
240
217
  return buildEnvelope(model, params);
241
218
  },
242
219
  });
243
220
  registerProvider({
244
- provider: 'kling',
245
- category: 'image',
221
+ provider: "kling",
222
+ category: "image",
246
223
  models: OMNI_IMAGE_MODELS,
247
224
  buildBody(model, prompt, flags) {
248
225
  if (flags.negativePrompt) {
249
226
  throw new CLIError(`Model "${model}" does not support --negative-prompt.`, ExitCode.USAGE);
250
227
  }
251
- if (flags.seriesAmount !== undefined && flags.resultType !== 'series') {
228
+ if (flags.seriesAmount !== undefined && flags.resultType !== "series") {
252
229
  throw new CLIError(`Model "${model}" requires --result-type series when using --series-amount.`, ExitCode.USAGE);
253
230
  }
254
- if (flags.resultType === 'series' && flags.n !== undefined) {
231
+ if (flags.resultType === "series" && flags.n !== undefined) {
255
232
  throw new CLIError(`Model "${model}" does not allow --n when --result-type series is selected.`, ExitCode.USAGE);
256
233
  }
257
234
  const params = { prompt };
258
235
  const imageList = buildOmniImageList(flags);
259
236
  if (imageList.length > 0)
260
- params['image_list'] = imageList;
237
+ params["image_list"] = imageList;
261
238
  if (flags.resolution)
262
- params['resolution'] = flags.resolution;
239
+ params["resolution"] = flags.resolution;
263
240
  if (flags.n !== undefined)
264
- params['n'] = flags.n;
241
+ params["n"] = flags.n;
265
242
  if (flags.aspectRatio)
266
- params['aspect_ratio'] = flags.aspectRatio;
243
+ params["aspect_ratio"] = flags.aspectRatio;
267
244
  if (flags.externalTaskId)
268
- params['external_task_id'] = flags.externalTaskId;
269
- if (model === 'kling_v3_omni_image') {
245
+ params["external_task_id"] = flags.externalTaskId;
246
+ if (model === "kling_v3_omni_image") {
270
247
  if (flags.resultType)
271
- params['result_type'] = flags.resultType;
248
+ params["result_type"] = flags.resultType;
272
249
  if (flags.seriesAmount !== undefined)
273
- params['series_amount'] = flags.seriesAmount;
250
+ params["series_amount"] = flags.seriesAmount;
274
251
  }
275
252
  return buildEnvelope(model, params);
276
253
  },
277
254
  });
278
255
  // ── Text-to-video ─────────────────────────────────────────────────────────────
279
256
  registerProvider({
280
- provider: 'kling',
281
- category: 'video',
257
+ provider: "kling",
258
+ category: "video",
282
259
  models: T2V_MODELS,
283
260
  requiresPrompt(model) {
284
261
  return T2V_SET.has(model);
@@ -291,8 +268,8 @@ registerProvider({
291
268
  });
292
269
  // ── Image-to-video ────────────────────────────────────────────────────────────
293
270
  registerProvider({
294
- provider: 'kling',
295
- category: 'video',
271
+ provider: "kling",
272
+ category: "video",
296
273
  models: I2V_MODELS,
297
274
  requiresPrompt() {
298
275
  return false;
@@ -305,31 +282,27 @@ registerProvider({
305
282
  }
306
283
  const params = {};
307
284
  if (prompt)
308
- params['prompt'] = prompt;
285
+ params["prompt"] = prompt;
309
286
  if (image)
310
- params['image'] = image;
287
+ params["image"] = image;
311
288
  if (imageTail)
312
- params['image_tail'] = imageTail;
289
+ params["image_tail"] = imageTail;
313
290
  applyCommonParams(params, flags);
314
291
  return buildEnvelope(model, params);
315
292
  },
316
293
  });
317
294
  // ── Avatar video ──────────────────────────────────────────────────────────────
318
295
  registerProvider({
319
- provider: 'kling',
320
- category: 'video',
296
+ provider: "kling",
297
+ category: "video",
321
298
  models: AVATAR_MODELS,
322
299
  requiresPrompt() {
323
300
  return false;
324
301
  },
325
302
  buildBody(model, prompt, flags) {
326
303
  const image = requireStringFlag(flags.imageUrl, `Model "${model}" requires --image-url.`);
327
- const audioId = typeof flags.audioId === 'string' && flags.audioId.length > 0
328
- ? flags.audioId
329
- : undefined;
330
- const soundFile = typeof flags.audioUrl === 'string' && flags.audioUrl.length > 0
331
- ? flags.audioUrl
332
- : undefined;
304
+ const audioId = typeof flags.audioId === "string" && flags.audioId.length > 0 ? flags.audioId : undefined;
305
+ const soundFile = typeof flags.audioUrl === "string" && flags.audioUrl.length > 0 ? flags.audioUrl : undefined;
333
306
  if (audioId && soundFile) {
334
307
  throw new CLIError(`Model "${model}" accepts either --audio-id or --audio-url, not both.`, ExitCode.USAGE);
335
308
  }
@@ -338,15 +311,15 @@ registerProvider({
338
311
  }
339
312
  const params = { image };
340
313
  if (audioId)
341
- params['audio_id'] = audioId;
314
+ params["audio_id"] = audioId;
342
315
  if (soundFile)
343
- params['sound_file'] = soundFile;
316
+ params["sound_file"] = soundFile;
344
317
  if (prompt)
345
- params['prompt'] = prompt;
318
+ params["prompt"] = prompt;
346
319
  if (flags.mode)
347
- params['mode'] = flags.mode;
320
+ params["mode"] = flags.mode;
348
321
  if (flags.externalTaskId)
349
- params['external_task_id'] = flags.externalTaskId;
322
+ params["external_task_id"] = flags.externalTaskId;
350
323
  return buildEnvelope(model, params);
351
324
  },
352
325
  });
@@ -357,7 +330,7 @@ function buildEffectsBody(model, flags, expectedImages) {
357
330
  throw new CLIError(`Model "${model}" requires --image-url or --image-urls.`, ExitCode.USAGE);
358
331
  }
359
332
  if (expectedImages !== undefined && images.length !== expectedImages) {
360
- throw new CLIError(`Model "${model}" requires exactly ${expectedImages} input image${expectedImages === 1 ? '' : 's'}.`, ExitCode.USAGE);
333
+ throw new CLIError(`Model "${model}" requires exactly ${expectedImages} input image${expectedImages === 1 ? "" : "s"}.`, ExitCode.USAGE);
361
334
  }
362
335
  const effectScene = requireStringFlag(flags.effectScene, `Model "${model}" requires --effect-scene.`);
363
336
  const duration = requireNumberFlag(flags.duration, `Model "${model}" requires --duration.`);
@@ -369,12 +342,12 @@ function buildEffectsBody(model, flags, expectedImages) {
369
342
  effect_scene: effectScene,
370
343
  };
371
344
  if (flags.externalTaskId)
372
- params['external_task_id'] = flags.externalTaskId;
345
+ params["external_task_id"] = flags.externalTaskId;
373
346
  return buildEnvelope(model, params);
374
347
  }
375
348
  registerProvider({
376
- provider: 'kling',
377
- category: 'video',
349
+ provider: "kling",
350
+ category: "video",
378
351
  models: EFFECTS_SINGLE_MODELS,
379
352
  requiresPrompt() {
380
353
  return false;
@@ -384,8 +357,8 @@ registerProvider({
384
357
  },
385
358
  });
386
359
  registerProvider({
387
- provider: 'kling',
388
- category: 'video',
360
+ provider: "kling",
361
+ category: "video",
389
362
  models: EFFECTS_MULTI_MODELS,
390
363
  requiresPrompt() {
391
364
  return false;
@@ -396,8 +369,8 @@ registerProvider({
396
369
  });
397
370
  // ── Motion control ────────────────────────────────────────────────────────────
398
371
  registerProvider({
399
- provider: 'kling',
400
- category: 'video',
372
+ provider: "kling",
373
+ category: "video",
401
374
  models: MOTION_CONTROL_MODELS,
402
375
  requiresPrompt() {
403
376
  return false;
@@ -414,21 +387,21 @@ registerProvider({
414
387
  mode,
415
388
  };
416
389
  if (prompt)
417
- params['prompt'] = prompt;
390
+ params["prompt"] = prompt;
418
391
  if (flags.keepOriginalSound)
419
- params['keep_original_sound'] = flags.keepOriginalSound;
392
+ params["keep_original_sound"] = flags.keepOriginalSound;
420
393
  if (flags.externalTaskId)
421
- params['external_task_id'] = flags.externalTaskId;
422
- if (model === 'kling_v3_motion_control' && flags.watermark !== undefined) {
423
- params['watermark_info'] = { enabled: flags.watermark };
394
+ params["external_task_id"] = flags.externalTaskId;
395
+ if (model === "kling_v3_motion_control" && flags.watermark !== undefined) {
396
+ params["watermark_info"] = { enabled: flags.watermark };
424
397
  }
425
398
  return buildEnvelope(model, params);
426
399
  },
427
400
  });
428
401
  // ── Duration extension ────────────────────────────────────────────────────────
429
402
  registerProvider({
430
- provider: 'kling',
431
- category: 'video',
403
+ provider: "kling",
404
+ category: "video",
432
405
  models: DURATION_EXTENSION_MODELS,
433
406
  requiresPrompt() {
434
407
  return false;
@@ -441,22 +414,22 @@ registerProvider({
441
414
  duration: String(duration),
442
415
  };
443
416
  if (flags.aspectRatio)
444
- params['aspect_ratio'] = flags.aspectRatio;
417
+ params["aspect_ratio"] = flags.aspectRatio;
445
418
  if (flags.extensionType)
446
- params['extension_type'] = flags.extensionType;
419
+ params["extension_type"] = flags.extensionType;
447
420
  if (flags.videoQuality)
448
- params['quality'] = flags.videoQuality;
421
+ params["quality"] = flags.videoQuality;
449
422
  if (flags.seed !== undefined)
450
- params['seed'] = flags.seed;
423
+ params["seed"] = flags.seed;
451
424
  if (flags.externalTaskId)
452
- params['external_task_id'] = flags.externalTaskId;
425
+ params["external_task_id"] = flags.externalTaskId;
453
426
  return buildEnvelope(model, params);
454
427
  },
455
428
  });
456
429
  // ── Lipsync video ────────────────────────────────────────────────────────────
457
430
  registerProvider({
458
- provider: 'kling',
459
- category: 'video',
431
+ provider: "kling",
432
+ category: "video",
460
433
  models: LIPSYNC_MODELS,
461
434
  requiresPrompt() {
462
435
  return false;
@@ -468,25 +441,25 @@ registerProvider({
468
441
  mode,
469
442
  [videoSource.key]: videoSource.value,
470
443
  };
471
- if (mode === 'text2video') {
444
+ if (mode === "text2video") {
472
445
  if (!prompt) {
473
446
  throw new CLIError(`Model "${model}" requires --prompt when --lipsync-mode text2video is used.`, ExitCode.USAGE);
474
447
  }
475
- input['text'] = prompt;
476
- input['voice_id'] = requireStringFlag(flags.voiceId, `Model "${model}" requires --voice-id when --lipsync-mode text2video is used.`);
477
- input['voice_language'] = requireStringFlag(flags.voiceLanguage, `Model "${model}" requires --voice-language when --lipsync-mode text2video is used.`);
448
+ input["text"] = prompt;
449
+ input["voice_id"] = requireStringFlag(flags.voiceId, `Model "${model}" requires --voice-id when --lipsync-mode text2video is used.`);
450
+ input["voice_language"] = requireStringFlag(flags.voiceLanguage, `Model "${model}" requires --voice-language when --lipsync-mode text2video is used.`);
478
451
  if (flags.voiceSpeed !== undefined)
479
- input['voice_speed'] = flags.voiceSpeed;
452
+ input["voice_speed"] = flags.voiceSpeed;
480
453
  if (flags.audioUrl) {
481
454
  throw new CLIError(`Model "${model}" does not allow --audio-url when --lipsync-mode text2video is used.`, ExitCode.USAGE);
482
455
  }
483
456
  }
484
- else if (mode === 'audio2video') {
457
+ else if (mode === "audio2video") {
485
458
  if (prompt) {
486
459
  throw new CLIError(`Model "${model}" does not use --prompt when --lipsync-mode audio2video is used.`, ExitCode.USAGE);
487
460
  }
488
- input['audio_type'] = 'url';
489
- input['audio_url'] = requireStringFlag(flags.audioUrl, `Model "${model}" requires --audio-url when --lipsync-mode audio2video is used.`);
461
+ input["audio_type"] = "url";
462
+ input["audio_url"] = requireStringFlag(flags.audioUrl, `Model "${model}" requires --audio-url when --lipsync-mode audio2video is used.`);
490
463
  if (flags.voiceId || flags.voiceLanguage || flags.voiceSpeed !== undefined) {
491
464
  throw new CLIError(`Model "${model}" does not allow voice options when --lipsync-mode audio2video is used.`, ExitCode.USAGE);
492
465
  }
@@ -499,30 +472,30 @@ registerProvider({
499
472
  });
500
473
  // ── Omni video ───────────────────────────────────────────────────────────────
501
474
  registerProvider({
502
- provider: 'kling',
503
- category: 'video',
475
+ provider: "kling",
476
+ category: "video",
504
477
  models: OMNI_VIDEO_MODELS,
505
478
  buildBody(model, prompt, flags) {
506
479
  if (flags.multiShot === true) {
507
480
  throw new CLIError(`Model "${model}" does not yet support --multi-shot from the CLI because multi-shot prompt segments are not exposed yet.`, ExitCode.USAGE);
508
481
  }
509
- if (model === 'kling_omni_video' && flags.sound) {
482
+ if (model === "kling_omni_video" && flags.sound) {
510
483
  throw new CLIError(`Model "${model}" does not support --sound.`, ExitCode.USAGE);
511
484
  }
512
485
  if (flags.shotType) {
513
486
  throw new CLIError(`Model "${model}" does not support --shot-type in the current CLI implementation.`, ExitCode.USAGE);
514
487
  }
515
488
  const params = buildOmniVideoParams(model, prompt, flags);
516
- if (model === 'kling_v3_omni_video' && flags.sound) {
517
- params['sound'] = flags.sound;
489
+ if (model === "kling_v3_omni_video" && flags.sound) {
490
+ params["sound"] = flags.sound;
518
491
  }
519
492
  return buildEnvelope(model, params);
520
493
  },
521
494
  });
522
495
  // ── Video to audio ───────────────────────────────────────────────────────────
523
496
  registerProvider({
524
- provider: 'kling',
525
- category: 'audio',
497
+ provider: "kling",
498
+ category: "audio",
526
499
  models: VIDEO_TO_AUDIO_MODELS,
527
500
  requiresPrompt() {
528
501
  return false;
@@ -536,20 +509,20 @@ registerProvider({
536
509
  [videoSource.key]: videoSource.value,
537
510
  };
538
511
  if (flags.soundEffectPrompt)
539
- params['sound_effect_prompt'] = flags.soundEffectPrompt;
512
+ params["sound_effect_prompt"] = flags.soundEffectPrompt;
540
513
  if (flags.bgmPrompt)
541
- params['bgm_prompt'] = flags.bgmPrompt;
514
+ params["bgm_prompt"] = flags.bgmPrompt;
542
515
  if (flags.asmrMode !== undefined)
543
- params['asmr_mode'] = flags.asmrMode;
516
+ params["asmr_mode"] = flags.asmrMode;
544
517
  if (flags.externalTaskId)
545
- params['external_task_id'] = flags.externalTaskId;
518
+ params["external_task_id"] = flags.externalTaskId;
546
519
  return buildEnvelope(model, params);
547
520
  },
548
521
  });
549
522
  // ── Tencent Kling video ──────────────────────────────────────────────────────
550
523
  registerProvider({
551
- provider: 'tencent',
552
- category: 'video',
524
+ provider: "tencent",
525
+ category: "video",
553
526
  models: TENCENT_KLING_I2V_MODELS,
554
527
  buildBody(model, prompt, flags) {
555
528
  if (flags.multiShot === true) {
@@ -562,16 +535,16 @@ registerProvider({
562
535
  }
563
536
  const params = { prompt };
564
537
  if (image)
565
- params['image'] = image;
538
+ params["image"] = image;
566
539
  if (imageTail)
567
- params['image_tail'] = imageTail;
540
+ params["image_tail"] = imageTail;
568
541
  applyCommonParams(params, flags);
569
542
  return buildEnvelope(model, params);
570
543
  },
571
544
  });
572
545
  registerProvider({
573
- provider: 'tencent',
574
- category: 'video',
546
+ provider: "tencent",
547
+ category: "video",
575
548
  models: TENCENT_KLING_OMNI_VIDEO_MODELS,
576
549
  buildBody(model, prompt, flags) {
577
550
  if (flags.multiShot === true) {
@@ -582,7 +555,7 @@ registerProvider({
582
555
  }
583
556
  const params = buildOmniVideoParams(model, prompt, flags);
584
557
  if (flags.sound)
585
- params['sound'] = flags.sound;
558
+ params["sound"] = flags.sound;
586
559
  return buildEnvelope(model, params);
587
560
  },
588
561
  });