vidspotai-shared 1.0.124 → 1.0.126
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/lib/globals/aiModels/enums.d.ts +38 -0
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +49 -1
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/alibaba.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/alibaba.js +460 -53
- package/lib/globals/aiModels/providers/bytedance.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/bytedance.js +221 -39
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +178 -32
- package/lib/globals/aiModels/providers/kling.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/kling.js +86 -12
- package/lib/globals/aiModels/providers/minimax.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/minimax.js +77 -0
- package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/openai.js +12 -0
- package/lib/globals/aiModels/providers/pixverse.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/pixverse.js +101 -28
- package/lib/globals/aiModels/providers/runway.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/runway.js +450 -24
- package/lib/globals/aiModels/providers/xai.d.ts +4 -0
- package/lib/globals/aiModels/providers/xai.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/xai.js +72 -0
- package/lib/globals/aiModels/tierHelpers.d.ts +10 -0
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
- package/lib/globals/aiModels/tierHelpers.js +48 -7
- package/lib/globals/aiModels/types.d.ts +21 -0
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/models/image.model.d.ts +24 -0
- package/lib/models/image.model.d.ts.map +1 -1
- package/lib/models/image.model.js +12 -0
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/models/klingElement.model.d.ts +52 -0
- package/lib/models/klingElement.model.d.ts.map +1 -0
- package/lib/models/klingElement.model.js +24 -0
- package/lib/models/user.model.d.ts +7 -1
- package/lib/models/user.model.d.ts.map +1 -1
- package/lib/models/video.model.d.ts +11 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.d.ts +88 -0
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +27 -1
- package/lib/services/agent/executor/visual.d.ts.map +1 -1
- package/lib/services/agent/executor/visual.js +40 -2
- package/lib/services/agent/mentionedRefs.d.ts.map +1 -1
- package/lib/services/agent/mentionedRefs.js +4 -1
- package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
- package/lib/services/agent/planner/structuralRules.js +8 -3
- package/lib/services/agent/poster/posterAgent.schema.d.ts +3 -3
- package/lib/services/agent/providerFallback/chains.d.ts +25 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +59 -5
- package/lib/services/agent/repair/strategies/llmRepair.strategy.d.ts.map +1 -1
- package/lib/services/agent/repair/strategies/llmRepair.strategy.js +2 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts +31 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/animateImage.tool.js +10 -3
- package/lib/services/agent/tools/generateImage.tool.d.ts +8 -4
- package/lib/services/agent/tools/generateImage.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateImage.tool.js +24 -7
- package/lib/services/agent/tools/generateVideo.tool.d.ts +32 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateVideo.tool.js +37 -9
- package/lib/services/agent/tools/planVideo.tool.d.ts +19 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +40 -0
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.d.ts +6 -3
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.d.ts.map +1 -1
- package/lib/services/aiGen/canonicalAdapters/cameraControl.types.js +35 -0
- package/lib/services/aiGen/canonicalAdapters/cameraDirection.d.ts +36 -0
- package/lib/services/aiGen/canonicalAdapters/cameraDirection.d.ts.map +1 -0
- package/lib/services/aiGen/canonicalAdapters/cameraDirection.js +168 -0
- package/lib/services/aiGen/canonicalAdapters/index.d.ts +1 -0
- package/lib/services/aiGen/canonicalAdapters/index.d.ts.map +1 -1
- package/lib/services/aiGen/canonicalAdapters/index.js +1 -0
- package/lib/services/aiGen/canonicalAdapters/multiShot.types.d.ts +3 -2
- package/lib/services/aiGen/canonicalAdapters/multiShot.types.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.d.ts +40 -0
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +48 -2
- package/lib/services/aiGen/index.d.ts +1 -0
- package/lib/services/aiGen/index.d.ts.map +1 -1
- package/lib/services/aiGen/index.js +3 -0
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts +13 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.js +313 -33
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts +29 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.js +371 -54
- package/lib/services/aiGen/providers/google/google.service.d.ts +16 -0
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +372 -116
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +6 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/googleKeyPool.js +8 -0
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +17 -1
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +59 -3
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts +1 -1
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/klingCredits.js +19 -1
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts +37 -7
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/klingRequests.js +191 -13
- package/lib/services/aiGen/providers/kling/types.d.ts +78 -0
- package/lib/services/aiGen/providers/kling/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/minimax/minimax.service.d.ts +11 -2
- package/lib/services/aiGen/providers/minimax/minimax.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/minimax/minimax.service.js +168 -2
- package/lib/services/aiGen/providers/minimax/types.d.ts +63 -0
- package/lib/services/aiGen/providers/minimax/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts +12 -0
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +131 -17
- package/lib/services/aiGen/providers/runway/hostedModels.d.ts +84 -0
- package/lib/services/aiGen/providers/runway/hostedModels.d.ts.map +1 -0
- package/lib/services/aiGen/providers/runway/hostedModels.js +266 -0
- package/lib/services/aiGen/providers/runway/index.d.ts +1 -0
- package/lib/services/aiGen/providers/runway/index.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/index.js +1 -0
- package/lib/services/aiGen/providers/runway/runway.service.d.ts +1 -1
- package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/runway.service.js +118 -21
- package/lib/services/aiGen/providers/runway/types.d.ts +18 -3
- package/lib/services/aiGen/providers/runway/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/types.js +31 -3
- package/lib/services/aiGen/providers/types.d.ts +55 -0
- package/lib/services/aiGen/providers/types.d.ts.map +1 -1
- package/lib/services/aiGen/providers/xai/xai.service.d.ts +19 -0
- package/lib/services/aiGen/providers/xai/xai.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/xai/xai.service.js +205 -0
- package/lib/services/firestore.service.d.ts +4 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +5 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +2 -0
- package/lib/services/klingElements/klingElementLibrary.service.d.ts +37 -0
- package/lib/services/klingElements/klingElementLibrary.service.d.ts.map +1 -0
- package/lib/services/klingElements/klingElementLibrary.service.js +179 -0
- package/lib/services/trialGuard/index.d.ts +2 -0
- package/lib/services/trialGuard/index.d.ts.map +1 -0
- package/lib/services/trialGuard/index.js +17 -0
- package/lib/services/trialGuard/trialSignals.d.ts +88 -0
- package/lib/services/trialGuard/trialSignals.d.ts.map +1 -0
- package/lib/services/trialGuard/trialSignals.js +160 -0
- package/lib/utils/helpers.d.ts.map +1 -1
- package/lib/utils/helpers.js +5 -1
- package/package.json +2 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseAiGenProviderService } from "../baseAiGenProvider.service";
|
|
2
2
|
import { CreditUsageParams, VideoGenerationParams, VideoGenerationResult, VideoStatusParams, VideoStatusResult } from "../types";
|
|
3
|
+
import { KlingCreateElementRequest, KlingElementInfo, KlingElementTask } from "./types";
|
|
3
4
|
/**
|
|
4
5
|
* Kling runs TWO auth schemes. Verified against the live API 2026-07-22,
|
|
5
6
|
* re-verified 2026-09-16.
|
|
@@ -50,6 +51,13 @@ export declare class KlingService extends BaseAiGenProviderService {
|
|
|
50
51
|
* Polling likewise goes to checkTurboVideoStatus, never the v1 prober.
|
|
51
52
|
*/
|
|
52
53
|
private generateTurboVideo;
|
|
54
|
+
/**
|
|
55
|
+
* kling-3.0-omni submit on API 2.0. Single endpoint for every input mix
|
|
56
|
+
* (t2v / first-last frame / reference images / feature video / base-video
|
|
57
|
+
* edit) — buildOmni2VideoBody decides the contents[]. Shares Turbo's
|
|
58
|
+
* envelope, auth and poller.
|
|
59
|
+
*/
|
|
60
|
+
private generateOmni2Video;
|
|
53
61
|
/**
|
|
54
62
|
* Extend a previously-generated Kling video by ~4-5s. Takes the Kling task id
|
|
55
63
|
* of the source video (must have been generated by this Kling account).
|
|
@@ -62,9 +70,17 @@ export declare class KlingService extends BaseAiGenProviderService {
|
|
|
62
70
|
private generateAvatarVideo;
|
|
63
71
|
private requestWithTimeoutRetry;
|
|
64
72
|
checkVideoStatus(params: VideoStatusParams): Promise<VideoStatusResult>;
|
|
73
|
+
/** Submit an element-creation task. Returns Kling's task id. */
|
|
74
|
+
createElement(body: KlingCreateElementRequest): Promise<string>;
|
|
75
|
+
/** Poll one element-creation task. */
|
|
76
|
+
getElementTask(taskId: string): Promise<KlingElementTask>;
|
|
77
|
+
/** Kling's official preset elements (one page; ≤500 per page). */
|
|
78
|
+
listPresetElements(pageNum?: number, pageSize?: number): Promise<KlingElementInfo[]>;
|
|
79
|
+
/** Delete a custom element (presets can't be deleted). */
|
|
80
|
+
deleteElement(elementId: string): Promise<void>;
|
|
65
81
|
/**
|
|
66
82
|
* Pick the credential for the surface being called. The API 2.0 key is
|
|
67
|
-
* optional in env — only
|
|
83
|
+
* optional in env — only the API 2.0 models (turbo, 3.0-omni) need it — so its absence must not
|
|
68
84
|
* break the JWT models that make up the rest of the catalog. Failing here
|
|
69
85
|
* (rather than letting Kling return an opaque 401) means the scene fails at
|
|
70
86
|
* SUBMIT with no task id, which our refund policy treats as never-billed →
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"kling.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/kling.service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,gBAAgB,EAMjB,MAAM,SAAS,CAAC;AAoBjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7C;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,wBAAwB;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IASxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmD;;YAWlE,OAAO;IAiCf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAmFjC;;;;;;;;OAQG;YACW,kBAAkB;IAgChC;;;;;OAKG;YACW,kBAAkB;IA4BhC;;;;OAIG;YACW,WAAW;YA6BX,iBAAiB;YA6BjB,qBAAqB;YAgCrB,eAAe;YAkDf,mBAAmB;YAgCnB,uBAAuB;IAsI/B,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsB7E,gEAAgE;IAC1D,aAAa,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IASrE,sCAAsC;IAChC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAQ/D,kEAAkE;IAC5D,kBAAkB,CAAC,OAAO,SAAI,EAAE,QAAQ,SAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAUlF,0DAA0D;IACpD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAiBxB,cAAc,IAAI,MAAM;IAexB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAGjD"}
|
|
@@ -102,6 +102,9 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
102
102
|
if (params.modelKey === "kling-v3.0-turbo") {
|
|
103
103
|
return this.generateTurboVideo(params);
|
|
104
104
|
}
|
|
105
|
+
if (params.modelKey === "kling-v3.0-omni") {
|
|
106
|
+
return this.generateOmni2Video(params);
|
|
107
|
+
}
|
|
105
108
|
const modelId = aiModels_1.aiModelConfigs[params.modelKey]?.modelId;
|
|
106
109
|
if (!modelId)
|
|
107
110
|
throw new Error(`Unknown modelKey: ${params.modelKey}`);
|
|
@@ -146,6 +149,28 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
146
149
|
});
|
|
147
150
|
return { task: task.data.id, status: types_1.EVideoSceneStatus.TRIGGERED };
|
|
148
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* kling-3.0-omni submit on API 2.0. Single endpoint for every input mix
|
|
154
|
+
* (t2v / first-last frame / reference images / feature video / base-video
|
|
155
|
+
* edit) — buildOmni2VideoBody decides the contents[]. Shares Turbo's
|
|
156
|
+
* envelope, auth and poller.
|
|
157
|
+
*/
|
|
158
|
+
async generateOmni2Video(params) {
|
|
159
|
+
const modelId = aiModels_1.aiModelConfigs[params.modelKey]?.modelId;
|
|
160
|
+
if (!modelId)
|
|
161
|
+
throw new Error(`Unknown modelKey: ${params.modelKey}`);
|
|
162
|
+
const body = (0, klingRequests_1.buildOmni2VideoBody)(params);
|
|
163
|
+
const starttime = Date.now();
|
|
164
|
+
const task = await this.requestWithTimeoutRetry(`/omni-video/${modelId}`, "POST", body, 4, this.generateTimeout, "apiKey");
|
|
165
|
+
logger_1.logger.info("Kling generateOmni2Video submitted", {
|
|
166
|
+
modelKey: params.modelKey,
|
|
167
|
+
modelId,
|
|
168
|
+
contentTypes: body.contents.map((c) => c.type),
|
|
169
|
+
taskId: task.data.id,
|
|
170
|
+
durationMs: Date.now() - starttime,
|
|
171
|
+
});
|
|
172
|
+
return { task: task.data.id, status: types_1.EVideoSceneStatus.TRIGGERED };
|
|
173
|
+
}
|
|
149
174
|
/**
|
|
150
175
|
* Extend a previously-generated Kling video by ~4-5s. Takes the Kling task id
|
|
151
176
|
* of the source video (must have been generated by this Kling account).
|
|
@@ -368,14 +393,38 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
368
393
|
// API 2.0 task — different endpoint, array response, and "succeeded" vs
|
|
369
394
|
// v1's "succeed". The v1 prober would 404 down its whole endpoint list and
|
|
370
395
|
// report the task missing.
|
|
371
|
-
if (params.modelKey === "kling-v3.0-turbo") {
|
|
396
|
+
if (params.modelKey === "kling-v3.0-turbo" || params.modelKey === "kling-v3.0-omni") {
|
|
372
397
|
return (0, klingStatus_1.checkTurboVideoStatus)(deps, params);
|
|
373
398
|
}
|
|
374
399
|
return (0, klingStatus_1.checkRegularVideoStatus)(deps, params);
|
|
375
400
|
}
|
|
401
|
+
// ─── Element Library ──────────────────────────────────────────────────
|
|
402
|
+
// Same API key (and therefore the same Kling account) as kling-v3.0-omni,
|
|
403
|
+
// so element ids created here resolve in Omni generations. Ownership per
|
|
404
|
+
// end user is enforced one level up (KlingElementLibrary).
|
|
405
|
+
/** Submit an element-creation task. Returns Kling's task id. */
|
|
406
|
+
async createElement(body) {
|
|
407
|
+
const res = await this.request("/v1/general/advanced-custom-elements", "POST", body);
|
|
408
|
+
return unwrapKlingEnvelope(res, "create element").task_id;
|
|
409
|
+
}
|
|
410
|
+
/** Poll one element-creation task. */
|
|
411
|
+
async getElementTask(taskId) {
|
|
412
|
+
const res = await this.requestWithTimeoutRetry(`/v1/general/advanced-custom-elements/${encodeURIComponent(taskId)}`, "GET");
|
|
413
|
+
return unwrapKlingEnvelope(res, "query element");
|
|
414
|
+
}
|
|
415
|
+
/** Kling's official preset elements (one page; ≤500 per page). */
|
|
416
|
+
async listPresetElements(pageNum = 1, pageSize = 500) {
|
|
417
|
+
const res = await this.requestWithTimeoutRetry(`/v1/general/advanced-presets-elements?pageNum=${pageNum}&pageSize=${pageSize}`, "GET");
|
|
418
|
+
return unwrapKlingEnvelope(res, "list preset elements").flatMap((t) => t.task_result?.elements ?? []);
|
|
419
|
+
}
|
|
420
|
+
/** Delete a custom element (presets can't be deleted). */
|
|
421
|
+
async deleteElement(elementId) {
|
|
422
|
+
const res = await this.request("/v1/general/delete-advanced-elements", "POST", { element_id: elementId });
|
|
423
|
+
unwrapKlingEnvelope(res, "delete element");
|
|
424
|
+
}
|
|
376
425
|
/**
|
|
377
426
|
* Pick the credential for the surface being called. The API 2.0 key is
|
|
378
|
-
* optional in env — only
|
|
427
|
+
* optional in env — only the API 2.0 models (turbo, 3.0-omni) need it — so its absence must not
|
|
379
428
|
* break the JWT models that make up the rest of the catalog. Failing here
|
|
380
429
|
* (rather than letting Kling return an opaque 401) means the scene fails at
|
|
381
430
|
* SUBMIT with no task id, which our refund policy treats as never-billed →
|
|
@@ -387,7 +436,7 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
387
436
|
const apiKey = process.env.KLING_API_KEY;
|
|
388
437
|
if (!apiKey) {
|
|
389
438
|
// Operator detail goes to Loki/Slack; the user sees only the safe copy.
|
|
390
|
-
logger_1.logger.error("KLING_API_KEY is not set — Kling API 2.0 models (kling-v3.0-turbo) need a console-issued API key from https://kling.ai/dev/api-key. The legacy AK/SK JWT is rejected by that surface with HTTP 401 code 1002.");
|
|
439
|
+
logger_1.logger.error("KLING_API_KEY is not set — Kling API 2.0 models (kling-v3.0-turbo, kling-v3.0-omni) need a console-issued API key from https://kling.ai/dev/api-key. The legacy AK/SK JWT is rejected by that surface with HTTP 401 code 1002.");
|
|
391
440
|
throw new errors_1.UserFacingError("This model is temporarily unavailable. Please pick another model.", errors_1.USER_FACING_ERROR_CODES.PROVIDER_AUTH_ERROR);
|
|
392
441
|
}
|
|
393
442
|
return apiKey;
|
|
@@ -409,3 +458,10 @@ class KlingService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
409
458
|
}
|
|
410
459
|
}
|
|
411
460
|
exports.KlingService = KlingService;
|
|
461
|
+
/** Kling answers HTTP 200 with a non-zero `code` for request-level errors. */
|
|
462
|
+
function unwrapKlingEnvelope(res, what) {
|
|
463
|
+
if (res.code !== 0) {
|
|
464
|
+
throw new errors_1.UserFacingError(`Kling couldn't ${what}: ${res.message || `code ${res.code}`}`, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
|
|
465
|
+
}
|
|
466
|
+
return res.data;
|
|
467
|
+
}
|
|
@@ -5,5 +5,5 @@ import { CreditUsageParams } from "../types";
|
|
|
5
5
|
* (per-second, 5s-rounded), v2.6 (audio/noAudio tier table), and the base
|
|
6
6
|
* table with deferred I2V / generate_audio upcharges.
|
|
7
7
|
*/
|
|
8
|
-
export declare function getKlingCreditUsed({ modelKey, mode, duration, multiClip, audio, inputType, }: CreditUsageParams): number;
|
|
8
|
+
export declare function getKlingCreditUsed({ modelKey, mode: requestedMode, duration, multiClip, audio, inputType, resolution, }: CreditUsageParams): number;
|
|
9
9
|
//# sourceMappingURL=klingCredits.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"klingCredits.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingCredits.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"klingCredits.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingCredits.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,IAAI,EAAE,aAAa,EACnB,QAAY,EACZ,SAAiB,EACjB,KAAa,EACb,SAAS,EACT,UAAU,GACX,EAAE,iBAAiB,GAAG,MAAM,CAuF5B"}
|
|
@@ -5,15 +5,20 @@ const aiModels_1 = require("../../../../globals/aiModels");
|
|
|
5
5
|
const logger_1 = require("../../../../utils/logger");
|
|
6
6
|
const helpers_1 = require("../../../../utils/helpers");
|
|
7
7
|
const types_1 = require("../../types");
|
|
8
|
+
const klingRequests_1 = require("./klingRequests");
|
|
8
9
|
/**
|
|
9
10
|
* Kling credit calculation. Pure (config lookup + arithmetic) — broken out of
|
|
10
11
|
* KlingService.getCreditUsed. Handles the three pricing shapes: avatar
|
|
11
12
|
* (per-second, 5s-rounded), v2.6 (audio/noAudio tier table), and the base
|
|
12
13
|
* table with deferred I2V / generate_audio upcharges.
|
|
13
14
|
*/
|
|
14
|
-
function getKlingCreditUsed({ modelKey, mode
|
|
15
|
+
function getKlingCreditUsed({ modelKey, mode: requestedMode, duration = 5, multiClip = false, audio = false, inputType, resolution, }) {
|
|
15
16
|
const modelConfig = aiModels_1.aiModelConfigs[modelKey];
|
|
16
17
|
const applyFloor = !multiClip;
|
|
18
|
+
// Legacy default for the table-priced models. kling-3.0-omni reads
|
|
19
|
+
// `requestedMode` instead: its request builder defaults to 720p, and
|
|
20
|
+
// billing an unset mode as pro would charge the 1080p rate for a 720p clip.
|
|
21
|
+
const mode = requestedMode ?? types_1.EVideoMode.PROFESSIONAL;
|
|
17
22
|
// Avatar: per-second pricing based on mode. Kling lipsync bills in
|
|
18
23
|
// 5-second increments (a 7s clip is billed as 10s).
|
|
19
24
|
if (modelKey === "kling-avatar") {
|
|
@@ -35,6 +40,19 @@ function getKlingCreditUsed({ modelKey, mode = types_1.EVideoMode.PROFESSIONAL,
|
|
|
35
40
|
?? 0.112;
|
|
36
41
|
return (0, helpers_1.getCreditsFromCost)(perSecond * duration, applyFloor);
|
|
37
42
|
}
|
|
43
|
+
// kling-3.0-omni (API 2.0): per-second, three tiers by video input × native
|
|
44
|
+
// audio, keyed by the SAME resolution the request builder sends. Any video
|
|
45
|
+
// input wins over audio: Kling allows no native audio with a video attached.
|
|
46
|
+
if (modelKey === "kling-v3.0-omni") {
|
|
47
|
+
const res = (0, klingRequests_1.resolveKlingOmni2Resolution)(resolution, requestedMode);
|
|
48
|
+
const table = inputType === "video"
|
|
49
|
+
? modelConfig?.cost?.videoInputPerSecondByResolution
|
|
50
|
+
: audio
|
|
51
|
+
? modelConfig?.cost?.nativeAudioPerSecondByResolution
|
|
52
|
+
: modelConfig?.cost?.perSecondByResolution;
|
|
53
|
+
const perSecond = table?.[res] ?? 0.168;
|
|
54
|
+
return (0, helpers_1.getCreditsFromCost)(perSecond * duration, applyFloor);
|
|
55
|
+
}
|
|
38
56
|
// v2.6 splits cost by audio/noAudio tier (audio is 2× upcharge).
|
|
39
57
|
if (modelKey === "kling-v2.6") {
|
|
40
58
|
const branch = audio ? modelConfig?.cost?.audio : modelConfig?.cost?.noAudio;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { VideoGenerationParams } from "../types";
|
|
2
|
-
import {
|
|
2
|
+
import type { MultiShot } from "../../canonicalAdapters/multiShot.types";
|
|
3
|
+
import { KlingAvatarGenerateRequest, KlingImageToVideoRequest, KlingLipSyncRequest, KlingMotionControlRequest, KlingOmniVideoRequest, KlingOmni2Request, KlingOmni2Resolution, KlingTurboImageToVideoRequest, KlingTurboTextToVideoRequest, KlingVideoGenerateRequest } from "./types";
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Canonical multiShot → Kling 3.0's prompt-encoded storyboard,
|
|
6
|
+
* "shot 1, 3, words; shot 2, 2, words;" (kling.ai/document-api/api/video/
|
|
7
|
+
* 3-0-omni/text-to-video and 3-0-turbo/*, fetched 2026-09-29). Each shot is
|
|
8
|
+
* ≥ 1s and the shot durations must sum to the video duration: caller-supplied
|
|
9
|
+
* durations are kept when they already satisfy that, otherwise the total is
|
|
10
|
+
* split evenly (remainder to the earliest shots). Semicolons inside a shot's
|
|
11
|
+
* text would read as a separator, so they become commas.
|
|
9
12
|
*/
|
|
13
|
+
export declare function toKlingShotPrompt(shots: MultiShot, totalDuration: number): string;
|
|
10
14
|
/**
|
|
11
15
|
* text2video / image2video body. Routes by the presence of inputImageUrl and
|
|
12
|
-
* wires the shared optional fields (negative prompt, cfg, camera
|
|
16
|
+
* wires the shared optional fields (negative prompt, cfg, camera direction,
|
|
13
17
|
* audio/sound tier) plus the i2v-only mask / tail-frame fields.
|
|
14
18
|
*/
|
|
15
19
|
export declare function buildVideoGenerateRequest(params: VideoGenerationParams, modelId: string): KlingVideoGenerateRequest | KlingImageToVideoRequest;
|
|
@@ -42,4 +46,30 @@ export declare function buildLipSyncBody(params: VideoGenerationParams, sessionI
|
|
|
42
46
|
* an agent-authored scene may carry extras from a prior model.
|
|
43
47
|
*/
|
|
44
48
|
export declare function buildTurboVideoBody(params: VideoGenerationParams): KlingTurboTextToVideoRequest | KlingTurboImageToVideoRequest;
|
|
49
|
+
/**
|
|
50
|
+
* Output resolution for kling-3.0-omni. An explicit `resolution` wins (case-
|
|
51
|
+
* insensitive, so "4K" works); otherwise our canonical `mode` maps with
|
|
52
|
+
* Kling's own legacy equivalence (std=720p, pro=1080p, "4k"=4k). Shared with
|
|
53
|
+
* getKlingCreditUsed so the billed tier is always the requested tier.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveKlingOmni2Resolution(resolution: string | undefined, mode: string | undefined): KlingOmni2Resolution;
|
|
56
|
+
/**
|
|
57
|
+
* kling-3.0-omni body. Canonical params map onto contents[] as:
|
|
58
|
+
* inputImageUrl → first_frame
|
|
59
|
+
* lastFrameImageUrl → last_frame (only together with a first frame)
|
|
60
|
+
* referenceImageUrls → refer_image, ids image_1…image_n
|
|
61
|
+
* referenceVideoUrls → feature_video (style/motion reference), id video_1
|
|
62
|
+
* inputVideoUrl → base_video (the clip to EDIT), id video_1
|
|
63
|
+
* klingElements → element, ids element_1…element_n
|
|
64
|
+
* The prompt can cite those ids as @image_1 / @video_1 / @element_1.
|
|
65
|
+
*
|
|
66
|
+
* Audio: `audio: true` means native sound on a plain generation and "keep
|
|
67
|
+
* the original track" on a base-video edit. Kling allows no audio at all with
|
|
68
|
+
* a feature video, so there it is always "off".
|
|
69
|
+
*
|
|
70
|
+
* Kling's documented combination rules are enforced here so a bad mix fails
|
|
71
|
+
* at submit (no task id → full refund) with a readable message, instead of
|
|
72
|
+
* an opaque provider 400.
|
|
73
|
+
*/
|
|
74
|
+
export declare function buildOmni2VideoBody(params: VideoGenerationParams): KlingOmni2Request;
|
|
45
75
|
//# sourceMappingURL=klingRequests.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"klingRequests.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingRequests.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,EAEL,0BAA0B,EAE1B,wBAAwB,EACxB,mBAAmB,EAEnB,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"klingRequests.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/kling/klingRequests.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,EAEL,0BAA0B,EAE1B,wBAAwB,EACxB,mBAAmB,EAEnB,yBAAyB,EACzB,qBAAqB,EAGrB,iBAAiB,EACjB,oBAAoB,EAGpB,6BAA6B,EAI7B,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AAcjB;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAgBjF;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,MAAM,GACd,yBAAyB,GAAG,wBAAwB,CA+DtD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,qBAAqB,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,MAAM,GACd,qBAAqB,CA+CvB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,MAAM,GACd,yBAAyB,CAW3B;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,qBAAqB,GAC5B,0BAA0B,CAS5B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5C,mBAAmB,CAgBrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,qBAAqB,GAC5B,4BAA4B,GAAG,6BAA6B,CAoC9D;AAID;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,oBAAoB,CAKtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,GAAG,iBAAiB,CAkGpF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toKlingShotPrompt = toKlingShotPrompt;
|
|
3
4
|
exports.buildVideoGenerateRequest = buildVideoGenerateRequest;
|
|
4
5
|
exports.buildExtendBody = buildExtendBody;
|
|
5
6
|
exports.buildOmniVideoBody = buildOmniVideoBody;
|
|
@@ -7,8 +8,11 @@ exports.buildMotionControlBody = buildMotionControlBody;
|
|
|
7
8
|
exports.buildAvatarRequest = buildAvatarRequest;
|
|
8
9
|
exports.buildLipSyncBody = buildLipSyncBody;
|
|
9
10
|
exports.buildTurboVideoBody = buildTurboVideoBody;
|
|
11
|
+
exports.resolveKlingOmni2Resolution = resolveKlingOmni2Resolution;
|
|
12
|
+
exports.buildOmni2VideoBody = buildOmni2VideoBody;
|
|
10
13
|
const types_1 = require("../../types");
|
|
11
|
-
const
|
|
14
|
+
const cameraDirection_1 = require("../../canonicalAdapters/cameraDirection");
|
|
15
|
+
const errors_1 = require("../../../../utils/errors");
|
|
12
16
|
/**
|
|
13
17
|
* Pure request-body builders mapping our provider-agnostic
|
|
14
18
|
* VideoGenerationParams onto Kling's per-endpoint request shapes. No I/O —
|
|
@@ -16,12 +20,46 @@ const cameraAdapter_1 = require("./cameraAdapter");
|
|
|
16
20
|
* the per-endpoint field wiring testable in isolation and the service class a
|
|
17
21
|
* thin dispatcher.
|
|
18
22
|
*/
|
|
23
|
+
/** Kling 3.0 / 3.0 Turbo prompt-encoded multi-shot limits (docs, 2026-09-29). */
|
|
24
|
+
const KLING_MAX_SHOTS = 6;
|
|
25
|
+
const KLING_MAX_SHOT_CHARS = 512;
|
|
26
|
+
/**
|
|
27
|
+
* Canonical multiShot → Kling 3.0's prompt-encoded storyboard,
|
|
28
|
+
* "shot 1, 3, words; shot 2, 2, words;" (kling.ai/document-api/api/video/
|
|
29
|
+
* 3-0-omni/text-to-video and 3-0-turbo/*, fetched 2026-09-29). Each shot is
|
|
30
|
+
* ≥ 1s and the shot durations must sum to the video duration: caller-supplied
|
|
31
|
+
* durations are kept when they already satisfy that, otherwise the total is
|
|
32
|
+
* split evenly (remainder to the earliest shots). Semicolons inside a shot's
|
|
33
|
+
* text would read as a separator, so they become commas.
|
|
34
|
+
*/
|
|
35
|
+
function toKlingShotPrompt(shots, totalDuration) {
|
|
36
|
+
const count = Math.max(1, Math.min(shots.length, KLING_MAX_SHOTS, totalDuration));
|
|
37
|
+
const used = shots.slice(0, count);
|
|
38
|
+
const given = used.map((s) => s.duration);
|
|
39
|
+
const keepGiven = given.every((d) => d !== undefined && Number.isInteger(d) && d >= 1) &&
|
|
40
|
+
given.reduce((a, b) => a + b, 0) === totalDuration;
|
|
41
|
+
const base = Math.floor(totalDuration / count);
|
|
42
|
+
const remainder = totalDuration % count;
|
|
43
|
+
return used
|
|
44
|
+
.map((s, i) => {
|
|
45
|
+
const seconds = keepGiven ? given[i] : base + (i < remainder ? 1 : 0);
|
|
46
|
+
const words = s.prompt.replace(/;/g, ",").trim().slice(0, KLING_MAX_SHOT_CHARS);
|
|
47
|
+
return `shot ${i + 1}, ${seconds}, ${words};`;
|
|
48
|
+
})
|
|
49
|
+
.join(" ");
|
|
50
|
+
}
|
|
19
51
|
/**
|
|
20
52
|
* text2video / image2video body. Routes by the presence of inputImageUrl and
|
|
21
|
-
* wires the shared optional fields (negative prompt, cfg, camera
|
|
53
|
+
* wires the shared optional fields (negative prompt, cfg, camera direction,
|
|
22
54
|
* audio/sound tier) plus the i2v-only mask / tail-frame fields.
|
|
23
55
|
*/
|
|
24
56
|
function buildVideoGenerateRequest(params, modelId) {
|
|
57
|
+
params = (0, cameraDirection_1.applyCameraDirection)(params);
|
|
58
|
+
// Kling 3.0 reads multi-shot from the prompt (no multi_prompt[] on this
|
|
59
|
+
// endpoint) — before this, a v3.0 multiShot request was silently dropped.
|
|
60
|
+
if (params.multiShot?.length && params.modelKey === "kling-v3.0") {
|
|
61
|
+
params = { ...params, prompt: toKlingShotPrompt(params.multiShot, params.duration ?? 5) };
|
|
62
|
+
}
|
|
25
63
|
// Common optional fields shared by text2video and image2video endpoints.
|
|
26
64
|
const optional = {};
|
|
27
65
|
if (params.negativePrompt)
|
|
@@ -32,20 +70,24 @@ function buildVideoGenerateRequest(params, modelId) {
|
|
|
32
70
|
optional.callback_url = params.callbackUrl;
|
|
33
71
|
if (params.externalTaskId)
|
|
34
72
|
optional.external_task_id = params.externalTaskId;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
73
|
+
// Kling's current text2video / image2video docs (2.5-turbo, 2.6, v3 —
|
|
74
|
+
// kling.ai/document-api/api/video/2-6/*, fetched 2026-09-29) no longer list
|
|
75
|
+
// `camera_control`; camera moves go in the prompt. applyCameraDirection
|
|
76
|
+
// (top of this function) does that.
|
|
77
|
+
// REMOVED FOR v2 — kept for reference:
|
|
78
|
+
// if (params.cameraControl) {
|
|
79
|
+
// const cc = toKlingCameraControl(params.cameraControl);
|
|
80
|
+
// if (cc) optional.camera_control = cc;
|
|
81
|
+
// }
|
|
82
|
+
// Native audio is `sound: "on"|"off"` on every model that has it (2.6 and
|
|
83
|
+
// v3 per the capability map; 2.5-turbo has none). The docs have no
|
|
84
|
+
// `generate_audio` field — sending it for v3 left audio off.
|
|
42
85
|
if (params.audio !== undefined) {
|
|
43
|
-
if (params.modelKey === "kling-v3.0") {
|
|
44
|
-
optional.generate_audio = Boolean(params.audio);
|
|
45
|
-
}
|
|
46
|
-
else if (params.modelKey === "kling-v2.6") {
|
|
86
|
+
if (params.modelKey === "kling-v3.0" || params.modelKey === "kling-v2.6") {
|
|
47
87
|
optional.sound = params.audio ? "on" : "off";
|
|
48
88
|
}
|
|
89
|
+
// REMOVED FOR v2 — kept for reference: the undocumented v3 flag.
|
|
90
|
+
// if (params.modelKey === "kling-v3.0") optional.generate_audio = Boolean(params.audio);
|
|
49
91
|
}
|
|
50
92
|
const isImageToVideo = !!params.inputImageUrl;
|
|
51
93
|
if (isImageToVideo) {
|
|
@@ -97,6 +139,7 @@ function buildExtendBody(params) {
|
|
|
97
139
|
}
|
|
98
140
|
/** OmniVideo body: start/end/reference frames, reference videos, multi-shot. */
|
|
99
141
|
function buildOmniVideoBody(params, modelId) {
|
|
142
|
+
params = (0, cameraDirection_1.applyCameraDirection)(params);
|
|
100
143
|
const body = {
|
|
101
144
|
model_name: modelId,
|
|
102
145
|
mode: params.mode || types_1.EVideoMode.STANDARD,
|
|
@@ -225,6 +268,10 @@ function buildTurboVideoBody(params) {
|
|
|
225
268
|
options.watermark_info = { enabled: Boolean(params.watermark) };
|
|
226
269
|
}
|
|
227
270
|
const maybeOptions = Object.keys(options).length ? { options } : {};
|
|
271
|
+
// Turbo multi-shot is the same prompt-encoded storyboard as 3.0.
|
|
272
|
+
if (params.multiShot?.length) {
|
|
273
|
+
params = { ...params, prompt: toKlingShotPrompt(params.multiShot, settings.duration ?? 5) };
|
|
274
|
+
}
|
|
228
275
|
if (params.inputImageUrl) {
|
|
229
276
|
// I2V: prompt and image BOTH ride inside contents[].
|
|
230
277
|
const contents = [];
|
|
@@ -236,3 +283,134 @@ function buildTurboVideoBody(params) {
|
|
|
236
283
|
// T2V: prompt is a top-level string on this endpoint (not contents[]).
|
|
237
284
|
return { prompt: params.prompt, settings, ...maybeOptions };
|
|
238
285
|
}
|
|
286
|
+
// ─── Kling 3.0 Omni, API 2.0 (POST /omni-video/kling-3.0-omni) ──────────────
|
|
287
|
+
/**
|
|
288
|
+
* Output resolution for kling-3.0-omni. An explicit `resolution` wins (case-
|
|
289
|
+
* insensitive, so "4K" works); otherwise our canonical `mode` maps with
|
|
290
|
+
* Kling's own legacy equivalence (std=720p, pro=1080p, "4k"=4k). Shared with
|
|
291
|
+
* getKlingCreditUsed so the billed tier is always the requested tier.
|
|
292
|
+
*/
|
|
293
|
+
function resolveKlingOmni2Resolution(resolution, mode) {
|
|
294
|
+
const r = resolution?.toLowerCase();
|
|
295
|
+
if (r === "720p" || r === "1080p" || r === "4k")
|
|
296
|
+
return r;
|
|
297
|
+
if (mode === "4k")
|
|
298
|
+
return "4k";
|
|
299
|
+
return mode === types_1.EVideoMode.PROFESSIONAL ? "1080p" : "720p";
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* kling-3.0-omni body. Canonical params map onto contents[] as:
|
|
303
|
+
* inputImageUrl → first_frame
|
|
304
|
+
* lastFrameImageUrl → last_frame (only together with a first frame)
|
|
305
|
+
* referenceImageUrls → refer_image, ids image_1…image_n
|
|
306
|
+
* referenceVideoUrls → feature_video (style/motion reference), id video_1
|
|
307
|
+
* inputVideoUrl → base_video (the clip to EDIT), id video_1
|
|
308
|
+
* klingElements → element, ids element_1…element_n
|
|
309
|
+
* The prompt can cite those ids as @image_1 / @video_1 / @element_1.
|
|
310
|
+
*
|
|
311
|
+
* Audio: `audio: true` means native sound on a plain generation and "keep
|
|
312
|
+
* the original track" on a base-video edit. Kling allows no audio at all with
|
|
313
|
+
* a feature video, so there it is always "off".
|
|
314
|
+
*
|
|
315
|
+
* Kling's documented combination rules are enforced here so a bad mix fails
|
|
316
|
+
* at submit (no task id → full refund) with a readable message, instead of
|
|
317
|
+
* an opaque provider 400.
|
|
318
|
+
*/
|
|
319
|
+
function buildOmni2VideoBody(params) {
|
|
320
|
+
const modelId = "kling-3.0-omni";
|
|
321
|
+
const refImages = params.referenceImageUrls ?? [];
|
|
322
|
+
const refVideos = params.referenceVideoUrls ?? [];
|
|
323
|
+
const baseVideo = params.inputVideoUrl;
|
|
324
|
+
const hasVideo = !!baseVideo || refVideos.length > 0;
|
|
325
|
+
const fail = (msg) => {
|
|
326
|
+
throw new errors_1.UserFacingError(`${modelId}: ${msg}`, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
|
|
327
|
+
};
|
|
328
|
+
if (params.lastFrameImageUrl && !params.inputImageUrl) {
|
|
329
|
+
fail("a last frame needs a first frame too.");
|
|
330
|
+
}
|
|
331
|
+
if (refVideos.length + (baseVideo ? 1 : 0) > 1) {
|
|
332
|
+
fail("takes at most one video (a reference video or a video to edit, not both).");
|
|
333
|
+
}
|
|
334
|
+
// REMOVED FOR v2 — kept for reference: image-only cap, before elements.
|
|
335
|
+
// const maxImages = hasVideo ? 4 : 7;
|
|
336
|
+
// if (refImages.length > maxImages) {
|
|
337
|
+
// fail(`takes at most ${maxImages} reference images${hasVideo ? " alongside a video" : ""} (got ${refImages.length}).`);
|
|
338
|
+
// }
|
|
339
|
+
// Element Library: multi-image elements share the reference-image budget;
|
|
340
|
+
// video-character elements have their own caps (Kling docs, 2026-09-29).
|
|
341
|
+
const elements = params.klingElements ?? [];
|
|
342
|
+
const imageElements = elements.filter((e) => e.referenceType === "image_refer").length;
|
|
343
|
+
const videoElements = elements.length - imageElements;
|
|
344
|
+
if (params.inputImageUrl && elements.length > 3) {
|
|
345
|
+
fail(`takes at most 3 elements with a first frame (got ${elements.length}).`);
|
|
346
|
+
}
|
|
347
|
+
if (hasVideo && videoElements > 0 && (imageElements > 0 || refImages.length > 0)) {
|
|
348
|
+
fail("with a video, a video-character element can't be combined with image elements or reference images.");
|
|
349
|
+
}
|
|
350
|
+
const maxVideoElements = hasVideo ? 1 : 3;
|
|
351
|
+
if (videoElements > maxVideoElements) {
|
|
352
|
+
fail(`takes at most ${maxVideoElements} video-character element${maxVideoElements > 1 ? "s" : ""}${hasVideo ? " alongside a video" : ""} (got ${videoElements}).`);
|
|
353
|
+
}
|
|
354
|
+
const maxImages = hasVideo || videoElements > 0 ? 4 : 7;
|
|
355
|
+
if (refImages.length + imageElements > maxImages) {
|
|
356
|
+
const what = imageElements ? "reference images + image elements" : "reference images";
|
|
357
|
+
const why = hasVideo ? " alongside a video" : videoElements > 0 ? " alongside a video-character element" : "";
|
|
358
|
+
fail(`takes at most ${maxImages} ${what}${why} (got ${refImages.length + imageElements}).`);
|
|
359
|
+
}
|
|
360
|
+
if (baseVideo && (params.inputImageUrl || params.lastFrameImageUrl)) {
|
|
361
|
+
fail("a video edit cannot also set a first or last frame.");
|
|
362
|
+
}
|
|
363
|
+
if (baseVideo && params.multiShot?.length) {
|
|
364
|
+
fail("a video edit cannot be multi-shot.");
|
|
365
|
+
}
|
|
366
|
+
const duration = params.duration ?? 5;
|
|
367
|
+
let prompt = params.prompt;
|
|
368
|
+
if (params.multiShot?.length)
|
|
369
|
+
prompt = toKlingShotPrompt(params.multiShot, duration);
|
|
370
|
+
if (!prompt)
|
|
371
|
+
fail("a prompt is required.");
|
|
372
|
+
if (prompt.length > 3072) {
|
|
373
|
+
throw new errors_1.UserFacingError(`${modelId} prompts are limited to 3072 characters (got ${prompt.length}).`, errors_1.USER_FACING_ERROR_CODES.PROMPT_TOO_LONG);
|
|
374
|
+
}
|
|
375
|
+
const contents = [{ type: "prompt", text: prompt }];
|
|
376
|
+
if (params.inputImageUrl)
|
|
377
|
+
contents.push({ type: "first_frame", url: params.inputImageUrl });
|
|
378
|
+
if (params.lastFrameImageUrl)
|
|
379
|
+
contents.push({ type: "last_frame", url: params.lastFrameImageUrl });
|
|
380
|
+
refImages.forEach((url, i) => contents.push({ type: "refer_image", url, id: `image_${i + 1}` }));
|
|
381
|
+
if (refVideos[0])
|
|
382
|
+
contents.push({ type: "feature_video", url: refVideos[0], id: "video_1" });
|
|
383
|
+
if (baseVideo)
|
|
384
|
+
contents.push({ type: "base_video", url: baseVideo, id: "video_1" });
|
|
385
|
+
elements.forEach((e, i) => contents.push({ type: "element", element_id: e.elementId, id: `element_${i + 1}` }));
|
|
386
|
+
// A feature (reference) video allows audio "off" only; a base-video edit
|
|
387
|
+
// allows "original" or "off"; native sound needs no video at all.
|
|
388
|
+
const audio = !params.audio || refVideos.length > 0
|
|
389
|
+
? "off"
|
|
390
|
+
: baseVideo ? "original" : "native";
|
|
391
|
+
const settings = {
|
|
392
|
+
resolution: resolveKlingOmni2Resolution(params.resolution, params.mode),
|
|
393
|
+
duration,
|
|
394
|
+
audio,
|
|
395
|
+
// Kling defaults multi_shot to TRUE, which lets it cut a single-prompt
|
|
396
|
+
// clip into shots on its own. Send it explicitly, on only when the caller
|
|
397
|
+
// asked for shots (base-video edits were rejected above for that).
|
|
398
|
+
multi_shot: !!params.multiShot?.length,
|
|
399
|
+
};
|
|
400
|
+
if (params.aspectRatio) {
|
|
401
|
+
settings.aspect_ratio = params.aspectRatio;
|
|
402
|
+
}
|
|
403
|
+
else if (!params.inputImageUrl && refVideos.length === 0) {
|
|
404
|
+
// Required by Kling when nothing else fixes the frame shape.
|
|
405
|
+
settings.aspect_ratio = "16:9";
|
|
406
|
+
}
|
|
407
|
+
const options = {};
|
|
408
|
+
if (params.callbackUrl)
|
|
409
|
+
options.callback_url = params.callbackUrl;
|
|
410
|
+
if (params.externalTaskId)
|
|
411
|
+
options.external_task_id = params.externalTaskId;
|
|
412
|
+
if (params.watermark !== undefined) {
|
|
413
|
+
options.watermark_info = { enabled: Boolean(params.watermark) };
|
|
414
|
+
}
|
|
415
|
+
return Object.keys(options).length ? { contents, settings, options } : { contents, settings };
|
|
416
|
+
}
|
|
@@ -259,4 +259,82 @@ export interface KlingTurboTasksResponse {
|
|
|
259
259
|
request_id: string;
|
|
260
260
|
data: KlingTurboTask[];
|
|
261
261
|
}
|
|
262
|
+
export type KlingOmni2Resolution = "720p" | "1080p" | "4k";
|
|
263
|
+
/** settings.audio — "original" keeps the reference/base video's own track. */
|
|
264
|
+
export type KlingOmni2Audio = "native" | "original" | "off";
|
|
265
|
+
/**
|
|
266
|
+
* contents[] entry. `id` is the handle the prompt cites (`@image_1`,
|
|
267
|
+
* `@video_1`) and must be unique within a task. `element` entries carry an
|
|
268
|
+
* `element_id` from Kling's Element Library instead of a url.
|
|
269
|
+
*/
|
|
270
|
+
export interface KlingOmni2Content {
|
|
271
|
+
type: "prompt" | "first_frame" | "last_frame" | "refer_image" | "feature_video" | "base_video" | "element";
|
|
272
|
+
/** Set when type === "prompt". Max 3072 chars. */
|
|
273
|
+
text?: string;
|
|
274
|
+
url?: string;
|
|
275
|
+
element_id?: string;
|
|
276
|
+
id?: string;
|
|
277
|
+
}
|
|
278
|
+
export interface KlingOmni2Settings {
|
|
279
|
+
/** Default true on Kling's side; forced true with a feature_video. */
|
|
280
|
+
multi_shot?: boolean;
|
|
281
|
+
audio?: KlingOmni2Audio;
|
|
282
|
+
resolution?: KlingOmni2Resolution;
|
|
283
|
+
/** Required when there is no first frame and no reference video. */
|
|
284
|
+
aspect_ratio?: KlingAspectRatio;
|
|
285
|
+
/** 3–15s inclusive. */
|
|
286
|
+
duration?: number;
|
|
287
|
+
}
|
|
288
|
+
export interface KlingOmni2Request {
|
|
289
|
+
contents: KlingOmni2Content[];
|
|
290
|
+
settings?: KlingOmni2Settings;
|
|
291
|
+
options?: KlingTurboOptions;
|
|
292
|
+
}
|
|
293
|
+
export interface KlingCreateElementRequest {
|
|
294
|
+
element_name: string;
|
|
295
|
+
element_description: string;
|
|
296
|
+
reference_type: "image_refer" | "video_refer";
|
|
297
|
+
/** Required for image_refer: 1 frontal + 1–3 other angles / close-ups. */
|
|
298
|
+
element_image_list?: {
|
|
299
|
+
frontal_image: string;
|
|
300
|
+
refer_images: {
|
|
301
|
+
image_url: string;
|
|
302
|
+
}[];
|
|
303
|
+
};
|
|
304
|
+
/** Required for video_refer: one .mp4/.mov, 3–8s, 1080p, 16:9 or 9:16, ≤200MB. */
|
|
305
|
+
element_video_list?: {
|
|
306
|
+
refer_videos: {
|
|
307
|
+
video_url: string;
|
|
308
|
+
}[];
|
|
309
|
+
};
|
|
310
|
+
element_voice_id?: string;
|
|
311
|
+
tag_list?: {
|
|
312
|
+
tag_id: string;
|
|
313
|
+
}[];
|
|
314
|
+
callback_url?: string;
|
|
315
|
+
external_task_id?: string;
|
|
316
|
+
}
|
|
317
|
+
export interface KlingElementInfo {
|
|
318
|
+
element_id: number | string;
|
|
319
|
+
element_name: string;
|
|
320
|
+
element_description: string;
|
|
321
|
+
reference_type: "image_refer" | "video_refer";
|
|
322
|
+
owned_by?: string;
|
|
323
|
+
status?: "succeed" | "deleted";
|
|
324
|
+
}
|
|
325
|
+
export interface KlingElementTask {
|
|
326
|
+
task_id: string;
|
|
327
|
+
task_status: "submitted" | "processing" | "succeed" | "failed";
|
|
328
|
+
task_status_msg?: string;
|
|
329
|
+
task_result?: {
|
|
330
|
+
elements?: KlingElementInfo[];
|
|
331
|
+
};
|
|
332
|
+
final_unit_deduction?: string;
|
|
333
|
+
}
|
|
334
|
+
export interface KlingEnvelope<T> {
|
|
335
|
+
code: number;
|
|
336
|
+
message: string;
|
|
337
|
+
request_id?: string;
|
|
338
|
+
data: T;
|
|
339
|
+
}
|
|
262
340
|
//# sourceMappingURL=types.d.ts.map
|