@juspay/neurolink 9.64.0 → 9.65.1
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/CHANGELOG.md +12 -0
- package/README.md +18 -17
- package/dist/adapters/providerImageAdapter.js +29 -1
- package/dist/adapters/replicate/auth.d.ts +19 -0
- package/dist/adapters/replicate/auth.js +32 -0
- package/dist/adapters/replicate/predictionLifecycle.d.ts +46 -0
- package/dist/adapters/replicate/predictionLifecycle.js +283 -0
- package/dist/adapters/video/klingVideoHandler.d.ts +37 -0
- package/dist/adapters/video/klingVideoHandler.js +305 -0
- package/dist/adapters/video/replicateVideoHandler.d.ts +29 -0
- package/dist/adapters/video/replicateVideoHandler.js +157 -0
- package/dist/adapters/video/runwayVideoHandler.d.ts +32 -0
- package/dist/adapters/video/runwayVideoHandler.js +316 -0
- package/dist/adapters/video/vertexVideoHandler.d.ts +19 -1
- package/dist/adapters/video/vertexVideoHandler.js +33 -9
- package/dist/agent/directTools.js +11 -3
- package/dist/autoresearch/runner.js +8 -2
- package/dist/avatar/index.d.ts +13 -0
- package/dist/avatar/index.js +13 -0
- package/dist/avatar/providers/DIDAvatar.d.ts +49 -0
- package/dist/avatar/providers/DIDAvatar.js +501 -0
- package/dist/avatar/providers/HeyGenAvatar.d.ts +30 -0
- package/dist/avatar/providers/HeyGenAvatar.js +337 -0
- package/dist/avatar/providers/ReplicateAvatar.d.ts +36 -0
- package/dist/avatar/providers/ReplicateAvatar.js +267 -0
- package/dist/browser/neurolink.min.js +624 -601
- package/dist/cli/commands/mcp.js +29 -0
- package/dist/cli/commands/proxy.js +24 -5
- package/dist/cli/factories/commandFactory.d.ts +11 -1
- package/dist/cli/factories/commandFactory.js +291 -38
- package/dist/constants/contextWindows.js +101 -0
- package/dist/constants/enums.d.ts +273 -2
- package/dist/constants/enums.js +290 -1
- package/dist/constants/videoErrors.d.ts +4 -0
- package/dist/constants/videoErrors.js +4 -0
- package/dist/core/baseProvider.d.ts +22 -2
- package/dist/core/baseProvider.js +217 -11
- package/dist/core/constants.d.ts +12 -0
- package/dist/core/constants.js +72 -1
- package/dist/evaluation/index.d.ts +2 -0
- package/dist/evaluation/index.js +4 -0
- package/dist/factories/providerFactory.js +7 -1
- package/dist/factories/providerRegistry.js +202 -5
- package/dist/features/ppt/contentPlanner.js +42 -14
- package/dist/index.d.ts +9 -1
- package/dist/index.js +16 -1
- package/dist/lib/adapters/providerImageAdapter.js +29 -1
- package/dist/lib/adapters/replicate/auth.d.ts +19 -0
- package/dist/lib/adapters/replicate/auth.js +33 -0
- package/dist/lib/adapters/replicate/predictionLifecycle.d.ts +46 -0
- package/dist/lib/adapters/replicate/predictionLifecycle.js +284 -0
- package/dist/lib/adapters/video/klingVideoHandler.d.ts +37 -0
- package/dist/lib/adapters/video/klingVideoHandler.js +306 -0
- package/dist/lib/adapters/video/replicateVideoHandler.d.ts +29 -0
- package/dist/lib/adapters/video/replicateVideoHandler.js +158 -0
- package/dist/lib/adapters/video/runwayVideoHandler.d.ts +32 -0
- package/dist/lib/adapters/video/runwayVideoHandler.js +317 -0
- package/dist/lib/adapters/video/vertexVideoHandler.d.ts +19 -1
- package/dist/lib/adapters/video/vertexVideoHandler.js +33 -9
- package/dist/lib/agent/directTools.js +11 -3
- package/dist/lib/autoresearch/runner.js +8 -2
- package/dist/lib/avatar/index.d.ts +13 -0
- package/dist/lib/avatar/index.js +14 -0
- package/dist/lib/avatar/providers/DIDAvatar.d.ts +49 -0
- package/dist/lib/avatar/providers/DIDAvatar.js +502 -0
- package/dist/lib/avatar/providers/HeyGenAvatar.d.ts +30 -0
- package/dist/lib/avatar/providers/HeyGenAvatar.js +338 -0
- package/dist/lib/avatar/providers/ReplicateAvatar.d.ts +36 -0
- package/dist/lib/avatar/providers/ReplicateAvatar.js +268 -0
- package/dist/lib/constants/contextWindows.js +101 -0
- package/dist/lib/constants/enums.d.ts +273 -2
- package/dist/lib/constants/enums.js +290 -1
- package/dist/lib/constants/videoErrors.d.ts +4 -0
- package/dist/lib/constants/videoErrors.js +4 -0
- package/dist/lib/core/baseProvider.d.ts +22 -2
- package/dist/lib/core/baseProvider.js +217 -11
- package/dist/lib/core/constants.d.ts +12 -0
- package/dist/lib/core/constants.js +72 -1
- package/dist/lib/evaluation/index.d.ts +2 -0
- package/dist/lib/evaluation/index.js +4 -0
- package/dist/lib/factories/providerFactory.js +7 -1
- package/dist/lib/factories/providerRegistry.js +202 -5
- package/dist/lib/features/ppt/contentPlanner.js +42 -14
- package/dist/lib/index.d.ts +9 -1
- package/dist/lib/index.js +16 -1
- package/dist/lib/middleware/builtin/lifecycle.js +39 -9
- package/dist/lib/music/index.d.ts +13 -0
- package/dist/lib/music/index.js +14 -0
- package/dist/lib/music/providers/BeatovenMusic.d.ts +31 -0
- package/dist/lib/music/providers/BeatovenMusic.js +334 -0
- package/dist/lib/music/providers/ElevenLabsMusic.d.ts +30 -0
- package/dist/lib/music/providers/ElevenLabsMusic.js +169 -0
- package/dist/lib/music/providers/LyriaMusic.d.ts +29 -0
- package/dist/lib/music/providers/LyriaMusic.js +173 -0
- package/dist/lib/music/providers/ReplicateMusic.d.ts +31 -0
- package/dist/lib/music/providers/ReplicateMusic.js +262 -0
- package/dist/lib/neurolink.d.ts +30 -0
- package/dist/lib/neurolink.js +323 -77
- package/dist/lib/providers/amazonBedrock.d.ts +10 -0
- package/dist/lib/providers/amazonBedrock.js +94 -39
- package/dist/lib/providers/anthropic.js +55 -7
- package/dist/lib/providers/anthropicBaseProvider.js +1 -1
- package/dist/lib/providers/azureOpenai.js +66 -17
- package/dist/lib/providers/cloudflare.d.ts +35 -0
- package/dist/lib/providers/cloudflare.js +174 -0
- package/dist/lib/providers/cohere.d.ts +52 -0
- package/dist/lib/providers/cohere.js +253 -0
- package/dist/lib/providers/deepseek.js +72 -17
- package/dist/lib/providers/fireworks.d.ts +33 -0
- package/dist/lib/providers/fireworks.js +164 -0
- package/dist/lib/providers/googleAiStudio.js +126 -10
- package/dist/lib/providers/googleNativeGemini3.d.ts +26 -6
- package/dist/lib/providers/googleNativeGemini3.js +276 -29
- package/dist/lib/providers/googleVertex.js +639 -181
- package/dist/lib/providers/groq.d.ts +33 -0
- package/dist/lib/providers/groq.js +181 -0
- package/dist/lib/providers/huggingFace.js +9 -8
- package/dist/lib/providers/ideogram.d.ts +34 -0
- package/dist/lib/providers/ideogram.js +184 -0
- package/dist/lib/providers/index.d.ts +13 -0
- package/dist/lib/providers/index.js +13 -0
- package/dist/lib/providers/jina.d.ts +59 -0
- package/dist/lib/providers/jina.js +218 -0
- package/dist/lib/providers/llamaCpp.js +14 -46
- package/dist/lib/providers/lmStudio.js +14 -47
- package/dist/lib/providers/mistral.js +7 -7
- package/dist/lib/providers/nvidiaNim.js +160 -19
- package/dist/lib/providers/ollama.js +7 -7
- package/dist/lib/providers/openAI.d.ts +22 -1
- package/dist/lib/providers/openAI.js +181 -0
- package/dist/lib/providers/openRouter.js +35 -23
- package/dist/lib/providers/openaiCompatible.js +9 -8
- package/dist/lib/providers/perplexity.d.ts +33 -0
- package/dist/lib/providers/perplexity.js +179 -0
- package/dist/lib/providers/recraft.d.ts +34 -0
- package/dist/lib/providers/recraft.js +197 -0
- package/dist/lib/providers/replicate.d.ts +75 -0
- package/dist/lib/providers/replicate.js +403 -0
- package/dist/lib/providers/stability.d.ts +37 -0
- package/dist/lib/providers/stability.js +191 -0
- package/dist/lib/providers/togetherAi.d.ts +33 -0
- package/dist/lib/providers/togetherAi.js +176 -0
- package/dist/lib/providers/voyage.d.ts +47 -0
- package/dist/lib/providers/voyage.js +177 -0
- package/dist/lib/providers/xai.d.ts +33 -0
- package/dist/lib/providers/xai.js +172 -0
- package/dist/lib/telemetry/index.d.ts +1 -1
- package/dist/lib/telemetry/index.js +1 -1
- package/dist/lib/telemetry/tracers.d.ts +19 -0
- package/dist/lib/telemetry/tracers.js +19 -0
- package/dist/lib/telemetry/withSpan.d.ts +35 -0
- package/dist/lib/telemetry/withSpan.js +103 -0
- package/dist/lib/types/avatar.d.ts +143 -0
- package/dist/lib/types/avatar.js +20 -0
- package/dist/lib/types/cli.d.ts +6 -0
- package/dist/lib/types/conversation.d.ts +16 -0
- package/dist/lib/types/generate.d.ts +62 -5
- package/dist/lib/types/index.d.ts +5 -0
- package/dist/lib/types/index.js +7 -0
- package/dist/lib/types/middleware.d.ts +27 -0
- package/dist/lib/types/multimodal.d.ts +35 -2
- package/dist/lib/types/music.d.ts +165 -0
- package/dist/lib/types/music.js +21 -0
- package/dist/lib/types/providers.d.ts +144 -1
- package/dist/lib/types/replicate.d.ts +67 -0
- package/dist/lib/types/replicate.js +10 -0
- package/dist/lib/types/safeFetch.d.ts +15 -0
- package/dist/lib/types/safeFetch.js +7 -0
- package/dist/lib/types/stream.d.ts +2 -1
- package/dist/lib/types/tools.d.ts +13 -0
- package/dist/lib/types/video.d.ts +89 -0
- package/dist/lib/types/video.js +15 -0
- package/dist/lib/utils/avatarProcessor.d.ts +68 -0
- package/dist/lib/utils/avatarProcessor.js +172 -0
- package/dist/lib/utils/cloneOptions.d.ts +36 -0
- package/dist/lib/utils/cloneOptions.js +62 -0
- package/dist/lib/utils/lifecycleCallbacks.d.ts +51 -8
- package/dist/lib/utils/lifecycleCallbacks.js +82 -26
- package/dist/lib/utils/lifecycleTimeout.d.ts +25 -0
- package/dist/lib/utils/lifecycleTimeout.js +39 -0
- package/dist/lib/utils/logSanitize.d.ts +49 -0
- package/dist/lib/utils/logSanitize.js +170 -0
- package/dist/lib/utils/loggingFetch.d.ts +29 -0
- package/dist/lib/utils/loggingFetch.js +60 -0
- package/dist/lib/utils/messageBuilder.js +43 -25
- package/dist/lib/utils/modelChoices.js +236 -3
- package/dist/lib/utils/musicProcessor.d.ts +67 -0
- package/dist/lib/utils/musicProcessor.js +189 -0
- package/dist/lib/utils/optionsConversion.js +3 -2
- package/dist/lib/utils/parameterValidation.js +14 -4
- package/dist/lib/utils/pricing.js +193 -0
- package/dist/lib/utils/providerConfig.d.ts +55 -0
- package/dist/lib/utils/providerConfig.js +224 -0
- package/dist/lib/utils/safeFetch.d.ts +26 -0
- package/dist/lib/utils/safeFetch.js +83 -0
- package/dist/lib/utils/sizeGuard.d.ts +34 -0
- package/dist/lib/utils/sizeGuard.js +45 -0
- package/dist/lib/utils/ssrfGuard.d.ts +52 -0
- package/dist/lib/utils/ssrfGuard.js +411 -0
- package/dist/lib/utils/videoProcessor.d.ts +60 -0
- package/dist/lib/utils/videoProcessor.js +201 -0
- package/dist/lib/voice/providers/FishAudioTTS.d.ts +27 -0
- package/dist/lib/voice/providers/FishAudioTTS.js +183 -0
- package/dist/lib/workflow/core/ensembleExecutor.js +26 -9
- package/dist/middleware/builtin/lifecycle.js +39 -9
- package/dist/music/index.d.ts +13 -0
- package/dist/music/index.js +13 -0
- package/dist/music/providers/BeatovenMusic.d.ts +31 -0
- package/dist/music/providers/BeatovenMusic.js +333 -0
- package/dist/music/providers/ElevenLabsMusic.d.ts +30 -0
- package/dist/music/providers/ElevenLabsMusic.js +168 -0
- package/dist/music/providers/LyriaMusic.d.ts +29 -0
- package/dist/music/providers/LyriaMusic.js +172 -0
- package/dist/music/providers/ReplicateMusic.d.ts +31 -0
- package/dist/music/providers/ReplicateMusic.js +261 -0
- package/dist/neurolink.d.ts +30 -0
- package/dist/neurolink.js +323 -77
- package/dist/providers/amazonBedrock.d.ts +10 -0
- package/dist/providers/amazonBedrock.js +94 -39
- package/dist/providers/anthropic.js +55 -7
- package/dist/providers/anthropicBaseProvider.js +1 -1
- package/dist/providers/azureOpenai.js +66 -17
- package/dist/providers/cloudflare.d.ts +35 -0
- package/dist/providers/cloudflare.js +173 -0
- package/dist/providers/cohere.d.ts +52 -0
- package/dist/providers/cohere.js +252 -0
- package/dist/providers/deepseek.js +72 -17
- package/dist/providers/fireworks.d.ts +33 -0
- package/dist/providers/fireworks.js +163 -0
- package/dist/providers/googleAiStudio.js +126 -10
- package/dist/providers/googleNativeGemini3.d.ts +26 -6
- package/dist/providers/googleNativeGemini3.js +276 -29
- package/dist/providers/googleVertex.js +639 -181
- package/dist/providers/groq.d.ts +33 -0
- package/dist/providers/groq.js +180 -0
- package/dist/providers/huggingFace.js +9 -8
- package/dist/providers/ideogram.d.ts +34 -0
- package/dist/providers/ideogram.js +183 -0
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/jina.d.ts +59 -0
- package/dist/providers/jina.js +217 -0
- package/dist/providers/llamaCpp.js +14 -46
- package/dist/providers/lmStudio.js +14 -47
- package/dist/providers/mistral.js +7 -7
- package/dist/providers/nvidiaNim.js +160 -19
- package/dist/providers/ollama.js +7 -7
- package/dist/providers/openAI.d.ts +22 -1
- package/dist/providers/openAI.js +181 -0
- package/dist/providers/openRouter.js +35 -23
- package/dist/providers/openaiCompatible.js +9 -8
- package/dist/providers/perplexity.d.ts +33 -0
- package/dist/providers/perplexity.js +178 -0
- package/dist/providers/recraft.d.ts +34 -0
- package/dist/providers/recraft.js +196 -0
- package/dist/providers/replicate.d.ts +75 -0
- package/dist/providers/replicate.js +402 -0
- package/dist/providers/stability.d.ts +37 -0
- package/dist/providers/stability.js +190 -0
- package/dist/providers/togetherAi.d.ts +33 -0
- package/dist/providers/togetherAi.js +175 -0
- package/dist/providers/voyage.d.ts +47 -0
- package/dist/providers/voyage.js +176 -0
- package/dist/providers/xai.d.ts +33 -0
- package/dist/providers/xai.js +171 -0
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/telemetry/tracers.d.ts +19 -0
- package/dist/telemetry/tracers.js +19 -0
- package/dist/telemetry/withSpan.d.ts +35 -0
- package/dist/telemetry/withSpan.js +103 -0
- package/dist/types/avatar.d.ts +143 -0
- package/dist/types/avatar.js +19 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/conversation.d.ts +16 -0
- package/dist/types/generate.d.ts +62 -5
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +7 -0
- package/dist/types/middleware.d.ts +27 -0
- package/dist/types/multimodal.d.ts +35 -2
- package/dist/types/music.d.ts +165 -0
- package/dist/types/music.js +20 -0
- package/dist/types/providers.d.ts +144 -1
- package/dist/types/replicate.d.ts +67 -0
- package/dist/types/replicate.js +9 -0
- package/dist/types/safeFetch.d.ts +15 -0
- package/dist/types/safeFetch.js +6 -0
- package/dist/types/stream.d.ts +2 -1
- package/dist/types/tools.d.ts +13 -0
- package/dist/types/video.d.ts +89 -0
- package/dist/types/video.js +14 -0
- package/dist/utils/avatarProcessor.d.ts +68 -0
- package/dist/utils/avatarProcessor.js +171 -0
- package/dist/utils/cloneOptions.d.ts +36 -0
- package/dist/utils/cloneOptions.js +61 -0
- package/dist/utils/lifecycleCallbacks.d.ts +51 -8
- package/dist/utils/lifecycleCallbacks.js +82 -26
- package/dist/utils/lifecycleTimeout.d.ts +25 -0
- package/dist/utils/lifecycleTimeout.js +38 -0
- package/dist/utils/logSanitize.d.ts +49 -0
- package/dist/utils/logSanitize.js +169 -0
- package/dist/utils/loggingFetch.d.ts +29 -0
- package/dist/utils/loggingFetch.js +59 -0
- package/dist/utils/messageBuilder.js +43 -25
- package/dist/utils/modelChoices.js +236 -3
- package/dist/utils/musicProcessor.d.ts +67 -0
- package/dist/utils/musicProcessor.js +188 -0
- package/dist/utils/optionsConversion.js +3 -2
- package/dist/utils/parameterValidation.js +14 -4
- package/dist/utils/pricing.js +193 -0
- package/dist/utils/providerConfig.d.ts +55 -0
- package/dist/utils/providerConfig.js +224 -0
- package/dist/utils/safeFetch.d.ts +26 -0
- package/dist/utils/safeFetch.js +82 -0
- package/dist/utils/sizeGuard.d.ts +34 -0
- package/dist/utils/sizeGuard.js +44 -0
- package/dist/utils/ssrfGuard.d.ts +52 -0
- package/dist/utils/ssrfGuard.js +410 -0
- package/dist/utils/videoProcessor.d.ts +60 -0
- package/dist/utils/videoProcessor.js +200 -0
- package/dist/voice/providers/FishAudioTTS.d.ts +27 -0
- package/dist/voice/providers/FishAudioTTS.js +182 -0
- package/dist/workflow/core/ensembleExecutor.js +26 -9
- package/package.json +32 -5
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kling Video Handler (PiAPI)
|
|
3
|
+
*
|
|
4
|
+
* Image-to-video generation via PiAPI's Kling endpoint. Async job model:
|
|
5
|
+
* POST /image-to-video → poll /task/{id} until completed.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: PiAPI Kling requires a publicly accessible image URL, not inline
|
|
8
|
+
* base64 data. Callers must supply `options.imageUrl` (a URL string) when
|
|
9
|
+
* using KlingVideoHandler. The `image` Buffer parameter is still accepted
|
|
10
|
+
* for interface compatibility (e.g., metadata / downstream use) but is not
|
|
11
|
+
* sent to the API. A clear error is thrown if no URL is provided.
|
|
12
|
+
*
|
|
13
|
+
* @module adapters/video/klingVideoHandler
|
|
14
|
+
* @see https://piapi.ai/docs/kling-api
|
|
15
|
+
*/
|
|
16
|
+
import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
|
|
17
|
+
import { VIDEO_ERROR_CODES } from "../../constants/videoErrors.js";
|
|
18
|
+
import { logger } from "../../utils/logger.js";
|
|
19
|
+
import { sanitizeForLog } from "../../utils/logSanitize.js";
|
|
20
|
+
import { safeDownload } from "../../utils/safeFetch.js";
|
|
21
|
+
import { VideoError } from "../../utils/videoProcessor.js";
|
|
22
|
+
import { MAX_VIDEO_BYTES } from "../../utils/sizeGuard.js";
|
|
23
|
+
const DEFAULT_BASE_URL = "https://api.piapi.ai/api/kling/v1";
|
|
24
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
25
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
26
|
+
const TOTAL_TIMEOUT_MS = 5 * 60_000;
|
|
27
|
+
/**
|
|
28
|
+
* Kling Video Handler.
|
|
29
|
+
*
|
|
30
|
+
* Auth: `Authorization: Bearer ${KLING_API_KEY}` (PiAPI / Kling key).
|
|
31
|
+
* Models: kling-1.6-i2v (default), kling-1.5-i2v, kling-1.0.
|
|
32
|
+
*/
|
|
33
|
+
export class KlingVideoHandler {
|
|
34
|
+
maxDurationSeconds = 10;
|
|
35
|
+
supportedAspectRatios = ["16:9", "9:16", "1:1"];
|
|
36
|
+
supportedResolutions = [
|
|
37
|
+
"720p",
|
|
38
|
+
"1080p",
|
|
39
|
+
];
|
|
40
|
+
apiKey;
|
|
41
|
+
baseUrl;
|
|
42
|
+
constructor(apiKey) {
|
|
43
|
+
const resolved = (apiKey ?? process.env.KLING_API_KEY ?? "").trim();
|
|
44
|
+
this.apiKey = resolved.length > 0 ? resolved : null;
|
|
45
|
+
this.baseUrl = (process.env.KLING_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
46
|
+
}
|
|
47
|
+
isConfigured() {
|
|
48
|
+
return this.apiKey !== null;
|
|
49
|
+
}
|
|
50
|
+
async generate(image, prompt, options) {
|
|
51
|
+
if (!this.apiKey) {
|
|
52
|
+
throw new VideoError({
|
|
53
|
+
code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
|
|
54
|
+
message: "KLING_API_KEY not configured",
|
|
55
|
+
category: ErrorCategory.CONFIGURATION,
|
|
56
|
+
severity: ErrorSeverity.HIGH,
|
|
57
|
+
retriable: false,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (!options.imageUrl) {
|
|
61
|
+
throw new VideoError({
|
|
62
|
+
code: VIDEO_ERROR_CODES.INVALID_INPUT,
|
|
63
|
+
message: "KlingVideoHandler requires a publicly accessible image URL. " +
|
|
64
|
+
"Pass options.imageUrl with a URL string pointing to the input image. " +
|
|
65
|
+
"The PiAPI Kling API does not accept inline base64 image data.",
|
|
66
|
+
category: ErrorCategory.CONFIGURATION,
|
|
67
|
+
severity: ErrorSeverity.HIGH,
|
|
68
|
+
retriable: false,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const startTime = Date.now();
|
|
72
|
+
const abortSignal = options.abortSignal;
|
|
73
|
+
// 1. Submit job.
|
|
74
|
+
const taskId = await this.submitJob(image, prompt, options);
|
|
75
|
+
// 2. Poll until complete.
|
|
76
|
+
const videoUrl = await this.pollUntilComplete(taskId, abortSignal);
|
|
77
|
+
// 3. Download video.
|
|
78
|
+
const buffer = await this.downloadVideo(videoUrl);
|
|
79
|
+
const processingTime = Date.now() - startTime;
|
|
80
|
+
logger.info(`[KlingVideoHandler] Generated ${buffer.length} bytes in ${processingTime}ms — task ${taskId}`);
|
|
81
|
+
return {
|
|
82
|
+
data: buffer,
|
|
83
|
+
mediaType: "video/mp4",
|
|
84
|
+
metadata: {
|
|
85
|
+
duration: options.length ?? 4,
|
|
86
|
+
dimensions: this.calculateDimensions(options),
|
|
87
|
+
model: options.model ?? "kling",
|
|
88
|
+
provider: "kling",
|
|
89
|
+
aspectRatio: options.aspectRatio ?? "16:9",
|
|
90
|
+
audioEnabled: false,
|
|
91
|
+
processingTime,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async submitJob(_image, prompt, options) {
|
|
96
|
+
// PiAPI Kling requires a publicly accessible URL for the input image.
|
|
97
|
+
// options.imageUrl is validated (non-null) before submitJob is called.
|
|
98
|
+
const body = {
|
|
99
|
+
model: options.model ?? "kling",
|
|
100
|
+
task_type: "video_generation",
|
|
101
|
+
input: {
|
|
102
|
+
image_url: options.imageUrl,
|
|
103
|
+
prompt,
|
|
104
|
+
duration: options.length ?? 4,
|
|
105
|
+
aspect_ratio: options.aspectRatio ?? "16:9",
|
|
106
|
+
cfg_scale: 0.5,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const response = await this.fetchWithTimeout(`${this.baseUrl}/image-to-video`, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
113
|
+
"Content-Type": "application/json",
|
|
114
|
+
},
|
|
115
|
+
body: JSON.stringify(body),
|
|
116
|
+
});
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
const raw = await response.text();
|
|
119
|
+
const retriable = response.status === 408 ||
|
|
120
|
+
response.status === 429 ||
|
|
121
|
+
response.status >= 500;
|
|
122
|
+
throw new VideoError({
|
|
123
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
124
|
+
message: `Kling submit failed: ${response.status} — ${sanitizeForLog(raw, 500)}`,
|
|
125
|
+
category: retriable ? ErrorCategory.NETWORK : ErrorCategory.EXECUTION,
|
|
126
|
+
severity: ErrorSeverity.HIGH,
|
|
127
|
+
retriable,
|
|
128
|
+
context: { status: response.status },
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const json = (await response.json());
|
|
132
|
+
const taskId = json.task_id ?? json.data?.task_id;
|
|
133
|
+
if (!taskId) {
|
|
134
|
+
throw new VideoError({
|
|
135
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
136
|
+
message: "Kling submit response missing task_id",
|
|
137
|
+
category: ErrorCategory.EXECUTION,
|
|
138
|
+
severity: ErrorSeverity.HIGH,
|
|
139
|
+
retriable: false,
|
|
140
|
+
context: { response: json },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return taskId;
|
|
144
|
+
}
|
|
145
|
+
async pollUntilComplete(taskId, abortSignal) {
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
while (Date.now() - startTime < TOTAL_TIMEOUT_MS) {
|
|
148
|
+
if (abortSignal?.aborted) {
|
|
149
|
+
throw new VideoError({
|
|
150
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
151
|
+
message: `Kling poll for task ${taskId} aborted by caller`,
|
|
152
|
+
category: ErrorCategory.NETWORK,
|
|
153
|
+
severity: ErrorSeverity.MEDIUM,
|
|
154
|
+
retriable: false,
|
|
155
|
+
context: { taskId },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const response = await this.fetchWithTimeout(`${this.baseUrl}/task/${taskId}`, {
|
|
159
|
+
method: "GET",
|
|
160
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
161
|
+
}, abortSignal);
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
const raw = await response.text();
|
|
164
|
+
throw new VideoError({
|
|
165
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
166
|
+
message: `Kling poll failed: ${response.status} — ${sanitizeForLog(raw, 500)}`,
|
|
167
|
+
category: ErrorCategory.NETWORK,
|
|
168
|
+
severity: ErrorSeverity.MEDIUM,
|
|
169
|
+
retriable: response.status >= 500,
|
|
170
|
+
context: { status: response.status, taskId },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const data = (await response.json());
|
|
174
|
+
if (data.status === "completed" || data.status === "succeeded") {
|
|
175
|
+
const videoUrl = data.video_url ?? data.output?.video_url;
|
|
176
|
+
if (!videoUrl) {
|
|
177
|
+
throw new VideoError({
|
|
178
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
179
|
+
message: `Kling task ${taskId} completed but no video URL returned`,
|
|
180
|
+
category: ErrorCategory.EXECUTION,
|
|
181
|
+
severity: ErrorSeverity.HIGH,
|
|
182
|
+
retriable: false,
|
|
183
|
+
context: { taskId, data },
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return videoUrl;
|
|
187
|
+
}
|
|
188
|
+
if (data.status === "failed") {
|
|
189
|
+
throw new VideoError({
|
|
190
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
191
|
+
message: `Kling task ${taskId} failed: ${data.error ?? "unknown"}`,
|
|
192
|
+
category: ErrorCategory.EXECUTION,
|
|
193
|
+
severity: ErrorSeverity.HIGH,
|
|
194
|
+
retriable: false,
|
|
195
|
+
context: { taskId, data },
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
// Abortable sleep.
|
|
199
|
+
await new Promise((resolve, reject) => {
|
|
200
|
+
const onAbort = () => {
|
|
201
|
+
clearTimeout(timer);
|
|
202
|
+
reject(new VideoError({
|
|
203
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
204
|
+
message: `Kling poll for task ${taskId} aborted by caller`,
|
|
205
|
+
category: ErrorCategory.NETWORK,
|
|
206
|
+
severity: ErrorSeverity.MEDIUM,
|
|
207
|
+
retriable: false,
|
|
208
|
+
context: { taskId },
|
|
209
|
+
}));
|
|
210
|
+
};
|
|
211
|
+
const timer = setTimeout(() => {
|
|
212
|
+
abortSignal?.removeEventListener("abort", onAbort);
|
|
213
|
+
resolve();
|
|
214
|
+
}, POLL_INTERVAL_MS);
|
|
215
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
throw new VideoError({
|
|
219
|
+
code: VIDEO_ERROR_CODES.POLL_TIMEOUT,
|
|
220
|
+
message: `Kling task ${taskId} did not complete within ${TOTAL_TIMEOUT_MS / 1000}s`,
|
|
221
|
+
category: ErrorCategory.TIMEOUT,
|
|
222
|
+
severity: ErrorSeverity.MEDIUM,
|
|
223
|
+
retriable: true,
|
|
224
|
+
context: { taskId },
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async downloadVideo(url) {
|
|
228
|
+
try {
|
|
229
|
+
return await safeDownload(url, {
|
|
230
|
+
maxBytes: MAX_VIDEO_BYTES,
|
|
231
|
+
label: "Kling video",
|
|
232
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
throw new VideoError({
|
|
237
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
238
|
+
message: `Kling video download rejected: ${err instanceof Error ? err.message : String(err)}`,
|
|
239
|
+
category: ErrorCategory.NETWORK,
|
|
240
|
+
severity: ErrorSeverity.HIGH,
|
|
241
|
+
retriable: false,
|
|
242
|
+
context: { url },
|
|
243
|
+
originalError: err instanceof Error ? err : undefined,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async fetchWithTimeout(url, init, callerAbortSignal) {
|
|
248
|
+
const controller = new AbortController();
|
|
249
|
+
let timedOut = false;
|
|
250
|
+
const timeoutId = setTimeout(() => {
|
|
251
|
+
timedOut = true;
|
|
252
|
+
controller.abort();
|
|
253
|
+
}, REQUEST_TIMEOUT_MS);
|
|
254
|
+
const onCallerAbort = () => controller.abort();
|
|
255
|
+
callerAbortSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
256
|
+
try {
|
|
257
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
261
|
+
if (timedOut) {
|
|
262
|
+
throw new VideoError({
|
|
263
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
264
|
+
message: `Kling request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
|
|
265
|
+
category: ErrorCategory.NETWORK,
|
|
266
|
+
severity: ErrorSeverity.HIGH,
|
|
267
|
+
retriable: true,
|
|
268
|
+
originalError: err,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
throw new VideoError({
|
|
272
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
273
|
+
message: "Kling request aborted by caller",
|
|
274
|
+
category: ErrorCategory.NETWORK,
|
|
275
|
+
severity: ErrorSeverity.MEDIUM,
|
|
276
|
+
retriable: false,
|
|
277
|
+
originalError: err,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
throw err;
|
|
281
|
+
}
|
|
282
|
+
finally {
|
|
283
|
+
callerAbortSignal?.removeEventListener("abort", onCallerAbort);
|
|
284
|
+
clearTimeout(timeoutId);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
calculateDimensions(options) {
|
|
288
|
+
const aspectRatio = options.aspectRatio ?? "16:9";
|
|
289
|
+
const resolution = options.resolution ?? "720p";
|
|
290
|
+
if (resolution === "1080p") {
|
|
291
|
+
if (aspectRatio === "1:1") {
|
|
292
|
+
return { width: 1080, height: 1080 };
|
|
293
|
+
}
|
|
294
|
+
return aspectRatio === "9:16"
|
|
295
|
+
? { width: 1080, height: 1920 }
|
|
296
|
+
: { width: 1920, height: 1080 };
|
|
297
|
+
}
|
|
298
|
+
if (aspectRatio === "1:1") {
|
|
299
|
+
return { width: 720, height: 720 };
|
|
300
|
+
}
|
|
301
|
+
return aspectRatio === "9:16"
|
|
302
|
+
? { width: 720, height: 1280 }
|
|
303
|
+
: { width: 1280, height: 720 };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replicate Video Handler
|
|
3
|
+
*
|
|
4
|
+
* Routes video generation through the universal Replicate prediction
|
|
5
|
+
* lifecycle. Default model is Wan-Alpha (RGBA video); callers can specify
|
|
6
|
+
* any image-to-video model on Replicate via `options.model`.
|
|
7
|
+
*
|
|
8
|
+
* @module adapters/video/replicateVideoHandler
|
|
9
|
+
* @see https://replicate.com/atonamy/wan-alpha
|
|
10
|
+
*/
|
|
11
|
+
import type { NeurolinkCredentials, VideoGenerationResult, VideoHandler, VideoOutputOptions } from "../../types/index.js";
|
|
12
|
+
/**
|
|
13
|
+
* Replicate Video Handler.
|
|
14
|
+
*
|
|
15
|
+
* Capabilities depend on the specific Replicate model — this handler
|
|
16
|
+
* advertises conservative bounds (any provider-supported aspect ratio /
|
|
17
|
+
* resolution; up to 10s typical for Wan-Alpha).
|
|
18
|
+
*/
|
|
19
|
+
export declare class ReplicateVideoHandler implements VideoHandler {
|
|
20
|
+
readonly maxDurationSeconds = 10;
|
|
21
|
+
readonly supportedAspectRatios: readonly ("9:16" | "16:9" | "1:1")[];
|
|
22
|
+
readonly supportedResolutions: readonly ("720p" | "1080p")[];
|
|
23
|
+
private readonly instanceCredentials;
|
|
24
|
+
constructor(credentials?: NeurolinkCredentials["replicate"]);
|
|
25
|
+
isConfigured(): boolean;
|
|
26
|
+
generate(image: Buffer, prompt: string, options: VideoOutputOptions): Promise<VideoGenerationResult>;
|
|
27
|
+
private detectImageType;
|
|
28
|
+
private calculateDimensions;
|
|
29
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replicate Video Handler
|
|
3
|
+
*
|
|
4
|
+
* Routes video generation through the universal Replicate prediction
|
|
5
|
+
* lifecycle. Default model is Wan-Alpha (RGBA video); callers can specify
|
|
6
|
+
* any image-to-video model on Replicate via `options.model`.
|
|
7
|
+
*
|
|
8
|
+
* @module adapters/video/replicateVideoHandler
|
|
9
|
+
* @see https://replicate.com/atonamy/wan-alpha
|
|
10
|
+
*/
|
|
11
|
+
import { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
|
|
12
|
+
import { VIDEO_ERROR_CODES } from "../../constants/videoErrors.js";
|
|
13
|
+
import { logger } from "../../utils/logger.js";
|
|
14
|
+
import { VideoError } from "../../utils/videoProcessor.js";
|
|
15
|
+
import { getReplicateAuth } from "../replicate/auth.js";
|
|
16
|
+
import { downloadPredictionOutput, predict, } from "../replicate/predictionLifecycle.js";
|
|
17
|
+
const DEFAULT_MODEL = "atonamy/wan-alpha";
|
|
18
|
+
/**
|
|
19
|
+
* Replicate Video Handler.
|
|
20
|
+
*
|
|
21
|
+
* Capabilities depend on the specific Replicate model — this handler
|
|
22
|
+
* advertises conservative bounds (any provider-supported aspect ratio /
|
|
23
|
+
* resolution; up to 10s typical for Wan-Alpha).
|
|
24
|
+
*/
|
|
25
|
+
export class ReplicateVideoHandler {
|
|
26
|
+
maxDurationSeconds = 10;
|
|
27
|
+
supportedAspectRatios = ["9:16", "16:9", "1:1"];
|
|
28
|
+
supportedResolutions = [
|
|
29
|
+
"720p",
|
|
30
|
+
"1080p",
|
|
31
|
+
];
|
|
32
|
+
instanceCredentials;
|
|
33
|
+
constructor(credentials) {
|
|
34
|
+
this.instanceCredentials = credentials;
|
|
35
|
+
}
|
|
36
|
+
isConfigured() {
|
|
37
|
+
return getReplicateAuth(this.instanceCredentials) !== null;
|
|
38
|
+
}
|
|
39
|
+
async generate(image, prompt, options) {
|
|
40
|
+
const perCallCreds = options.credentials?.replicate;
|
|
41
|
+
const auth = getReplicateAuth(perCallCreds ?? this.instanceCredentials);
|
|
42
|
+
if (!auth) {
|
|
43
|
+
throw new VideoError({
|
|
44
|
+
code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
|
|
45
|
+
message: "REPLICATE_API_TOKEN not configured",
|
|
46
|
+
category: ErrorCategory.CONFIGURATION,
|
|
47
|
+
severity: ErrorSeverity.HIGH,
|
|
48
|
+
retriable: false,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const startTime = Date.now();
|
|
52
|
+
const model = options.model ?? DEFAULT_MODEL;
|
|
53
|
+
const dataUri = `data:image/${this.detectImageType(image)};base64,${image.toString("base64")}`;
|
|
54
|
+
// Wan-Alpha + most image-to-video models accept this shape; specific
|
|
55
|
+
// models may require provider-specific extras passed through
|
|
56
|
+
// VideoOutputOptions.[unknown key].
|
|
57
|
+
//
|
|
58
|
+
// `resolution` is forwarded as the `resolution` input parameter.
|
|
59
|
+
// Wan-Alpha and several other Replicate image-to-video models accept it
|
|
60
|
+
// (e.g. "720p", "1080p"). Models that do not recognise it will silently
|
|
61
|
+
// ignore the field — the Replicate API does not reject unknown input keys.
|
|
62
|
+
// `calculateDimensions` still populates the metadata `dimensions` field
|
|
63
|
+
// so downstream consumers always receive correct width/height regardless
|
|
64
|
+
// of whether the model honoured the resolution hint.
|
|
65
|
+
const inputPayload = {
|
|
66
|
+
image: dataUri,
|
|
67
|
+
prompt,
|
|
68
|
+
num_frames: (options.length ?? 4) * 24, // Assume 24 fps
|
|
69
|
+
fps: 24,
|
|
70
|
+
aspect_ratio: options.aspectRatio,
|
|
71
|
+
...(options.resolution !== undefined
|
|
72
|
+
? { resolution: options.resolution }
|
|
73
|
+
: {}),
|
|
74
|
+
};
|
|
75
|
+
let prediction;
|
|
76
|
+
try {
|
|
77
|
+
prediction = await predict(auth, { model, input: inputPayload }, { abortSignal: options.abortSignal });
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
throw new VideoError({
|
|
81
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
82
|
+
message: `Replicate video generation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
83
|
+
category: ErrorCategory.EXECUTION,
|
|
84
|
+
severity: ErrorSeverity.HIGH,
|
|
85
|
+
retriable: true,
|
|
86
|
+
context: { model, options },
|
|
87
|
+
originalError: err instanceof Error ? err : undefined,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
let videoBuffer;
|
|
91
|
+
try {
|
|
92
|
+
videoBuffer = await downloadPredictionOutput(prediction);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
throw new VideoError({
|
|
96
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
97
|
+
message: `Replicate video download failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
98
|
+
category: ErrorCategory.NETWORK,
|
|
99
|
+
severity: ErrorSeverity.MEDIUM,
|
|
100
|
+
retriable: true,
|
|
101
|
+
context: { predictionId: prediction.id },
|
|
102
|
+
originalError: err instanceof Error ? err : undefined,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const processingTime = Date.now() - startTime;
|
|
106
|
+
logger.info(`[ReplicateVideoHandler] Generated ${videoBuffer.length} bytes in ${processingTime}ms — model ${model}`);
|
|
107
|
+
return {
|
|
108
|
+
data: videoBuffer,
|
|
109
|
+
mediaType: "video/mp4",
|
|
110
|
+
metadata: {
|
|
111
|
+
duration: options.length ?? 4,
|
|
112
|
+
dimensions: this.calculateDimensions(options),
|
|
113
|
+
model,
|
|
114
|
+
provider: "replicate",
|
|
115
|
+
aspectRatio: options.aspectRatio ?? "16:9",
|
|
116
|
+
audioEnabled: false, // Most Replicate video models are silent
|
|
117
|
+
processingTime,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
detectImageType(buffer) {
|
|
122
|
+
if (buffer.length < 4) {
|
|
123
|
+
return "jpeg";
|
|
124
|
+
}
|
|
125
|
+
if (buffer[0] === 0x89 && buffer[1] === 0x50) {
|
|
126
|
+
return "png";
|
|
127
|
+
}
|
|
128
|
+
if (buffer[0] === 0xff && buffer[1] === 0xd8) {
|
|
129
|
+
return "jpeg";
|
|
130
|
+
}
|
|
131
|
+
if (buffer[0] === 0x52 &&
|
|
132
|
+
buffer[1] === 0x49 &&
|
|
133
|
+
buffer[2] === 0x46 &&
|
|
134
|
+
buffer[3] === 0x46) {
|
|
135
|
+
return "webp";
|
|
136
|
+
}
|
|
137
|
+
return "jpeg";
|
|
138
|
+
}
|
|
139
|
+
calculateDimensions(options) {
|
|
140
|
+
const aspectRatio = options.aspectRatio ?? "16:9";
|
|
141
|
+
const resolution = options.resolution ?? "720p";
|
|
142
|
+
if (resolution === "1080p") {
|
|
143
|
+
if (aspectRatio === "1:1") {
|
|
144
|
+
return { width: 1080, height: 1080 };
|
|
145
|
+
}
|
|
146
|
+
return aspectRatio === "9:16"
|
|
147
|
+
? { width: 1080, height: 1920 }
|
|
148
|
+
: { width: 1920, height: 1080 };
|
|
149
|
+
}
|
|
150
|
+
if (aspectRatio === "1:1") {
|
|
151
|
+
return { width: 720, height: 720 };
|
|
152
|
+
}
|
|
153
|
+
return aspectRatio === "9:16"
|
|
154
|
+
? { width: 720, height: 1280 }
|
|
155
|
+
: { width: 1280, height: 720 };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runway Video Handler (Gen-3 Alpha / Gen-4 Turbo)
|
|
3
|
+
*
|
|
4
|
+
* Async generation: POST /v1/image_to_video → poll /v1/tasks/{id}.
|
|
5
|
+
*
|
|
6
|
+
* @module adapters/video/runwayVideoHandler
|
|
7
|
+
* @see https://docs.dev.runwayml.com/api/
|
|
8
|
+
*/
|
|
9
|
+
import type { VideoGenerationResult, VideoHandler, VideoOutputOptions } from "../../types/index.js";
|
|
10
|
+
/**
|
|
11
|
+
* Runway Video Handler.
|
|
12
|
+
*
|
|
13
|
+
* Auth: `Authorization: Bearer ${RUNWAY_API_KEY}` + `X-Runway-Version`
|
|
14
|
+
* header. Models: gen3a_turbo (Gen-3 Alpha Turbo, default), gen4_turbo.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RunwayVideoHandler implements VideoHandler {
|
|
17
|
+
readonly maxDurationSeconds = 10;
|
|
18
|
+
readonly supportedAspectRatios: readonly ("16:9" | "9:16")[];
|
|
19
|
+
readonly supportedResolutions: readonly ("720p" | "1080p")[];
|
|
20
|
+
private readonly apiKey;
|
|
21
|
+
private readonly baseUrl;
|
|
22
|
+
private readonly apiVersion;
|
|
23
|
+
constructor(apiKey?: string);
|
|
24
|
+
isConfigured(): boolean;
|
|
25
|
+
generate(image: Buffer, prompt: string, options: VideoOutputOptions): Promise<VideoGenerationResult>;
|
|
26
|
+
private submitTask;
|
|
27
|
+
private pollUntilComplete;
|
|
28
|
+
private downloadVideo;
|
|
29
|
+
private fetchWithTimeout;
|
|
30
|
+
private detectImageType;
|
|
31
|
+
private calculateDimensions;
|
|
32
|
+
}
|