@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,316 @@
|
|
|
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 { ErrorCategory, ErrorSeverity } from "../../constants/enums.js";
|
|
10
|
+
import { VIDEO_ERROR_CODES } from "../../constants/videoErrors.js";
|
|
11
|
+
import { logger } from "../../utils/logger.js";
|
|
12
|
+
import { sanitizeForLog } from "../../utils/logSanitize.js";
|
|
13
|
+
import { safeDownload } from "../../utils/safeFetch.js";
|
|
14
|
+
import { VideoError } from "../../utils/videoProcessor.js";
|
|
15
|
+
import { MAX_VIDEO_BYTES } from "../../utils/sizeGuard.js";
|
|
16
|
+
const DEFAULT_BASE_URL = "https://api.dev.runwayml.com/v1";
|
|
17
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
18
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
19
|
+
const TOTAL_TIMEOUT_MS = 5 * 60_000;
|
|
20
|
+
/**
|
|
21
|
+
* Runway Video Handler.
|
|
22
|
+
*
|
|
23
|
+
* Auth: `Authorization: Bearer ${RUNWAY_API_KEY}` + `X-Runway-Version`
|
|
24
|
+
* header. Models: gen3a_turbo (Gen-3 Alpha Turbo, default), gen4_turbo.
|
|
25
|
+
*/
|
|
26
|
+
export class RunwayVideoHandler {
|
|
27
|
+
maxDurationSeconds = 10;
|
|
28
|
+
supportedAspectRatios = [
|
|
29
|
+
"16:9",
|
|
30
|
+
"9:16",
|
|
31
|
+
];
|
|
32
|
+
supportedResolutions = [
|
|
33
|
+
"720p",
|
|
34
|
+
"1080p",
|
|
35
|
+
];
|
|
36
|
+
apiKey;
|
|
37
|
+
baseUrl;
|
|
38
|
+
apiVersion;
|
|
39
|
+
constructor(apiKey) {
|
|
40
|
+
const resolved = (apiKey ?? process.env.RUNWAY_API_KEY ?? "").trim();
|
|
41
|
+
this.apiKey = resolved.length > 0 ? resolved : null;
|
|
42
|
+
this.baseUrl = (process.env.RUNWAY_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
43
|
+
this.apiVersion = process.env.RUNWAY_API_VERSION ?? "2024-11-06";
|
|
44
|
+
}
|
|
45
|
+
isConfigured() {
|
|
46
|
+
return this.apiKey !== null;
|
|
47
|
+
}
|
|
48
|
+
async generate(image, prompt, options) {
|
|
49
|
+
if (!this.apiKey) {
|
|
50
|
+
throw new VideoError({
|
|
51
|
+
code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
|
|
52
|
+
message: "RUNWAY_API_KEY not configured",
|
|
53
|
+
category: ErrorCategory.CONFIGURATION,
|
|
54
|
+
severity: ErrorSeverity.HIGH,
|
|
55
|
+
retriable: false,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (options.aspectRatio !== undefined &&
|
|
59
|
+
!this.supportedAspectRatios.includes(options.aspectRatio)) {
|
|
60
|
+
throw new VideoError({
|
|
61
|
+
code: VIDEO_ERROR_CODES.INVALID_INPUT,
|
|
62
|
+
message: `Unsupported aspect ratio for Runway: "${options.aspectRatio}". Supported: ${this.supportedAspectRatios.join(", ")}.`,
|
|
63
|
+
category: ErrorCategory.VALIDATION,
|
|
64
|
+
severity: ErrorSeverity.MEDIUM,
|
|
65
|
+
retriable: false,
|
|
66
|
+
context: {
|
|
67
|
+
requested: options.aspectRatio,
|
|
68
|
+
supported: this.supportedAspectRatios,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
const abortSignal = options.abortSignal;
|
|
74
|
+
const taskId = await this.submitTask(image, prompt, options);
|
|
75
|
+
const videoUrl = await this.pollUntilComplete(taskId, abortSignal);
|
|
76
|
+
const buffer = await this.downloadVideo(videoUrl);
|
|
77
|
+
const processingTime = Date.now() - startTime;
|
|
78
|
+
logger.info(`[RunwayVideoHandler] Generated ${buffer.length} bytes in ${processingTime}ms — task ${taskId}`);
|
|
79
|
+
return {
|
|
80
|
+
data: buffer,
|
|
81
|
+
mediaType: "video/mp4",
|
|
82
|
+
metadata: {
|
|
83
|
+
duration: options.length ?? 4,
|
|
84
|
+
dimensions: this.calculateDimensions(options),
|
|
85
|
+
model: options.model ?? "gen3a_turbo",
|
|
86
|
+
provider: "runway",
|
|
87
|
+
aspectRatio: options.aspectRatio ?? "16:9",
|
|
88
|
+
audioEnabled: false,
|
|
89
|
+
processingTime,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async submitTask(image, prompt, options) {
|
|
94
|
+
const dataUri = `data:image/${this.detectImageType(image)};base64,${image.toString("base64")}`;
|
|
95
|
+
const body = {
|
|
96
|
+
model: options.model ?? "gen3a_turbo",
|
|
97
|
+
promptImage: dataUri,
|
|
98
|
+
promptText: prompt,
|
|
99
|
+
duration: options.length ?? 4,
|
|
100
|
+
ratio: options.aspectRatio === "9:16" ? "9:16" : "16:9",
|
|
101
|
+
seed: undefined,
|
|
102
|
+
};
|
|
103
|
+
const response = await this.fetchWithTimeout(`${this.baseUrl}/image_to_video`, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: {
|
|
106
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
107
|
+
"Content-Type": "application/json",
|
|
108
|
+
"X-Runway-Version": this.apiVersion,
|
|
109
|
+
},
|
|
110
|
+
body: JSON.stringify(body),
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
const raw = await response.text();
|
|
114
|
+
const retriable = response.status === 408 ||
|
|
115
|
+
response.status === 429 ||
|
|
116
|
+
response.status >= 500;
|
|
117
|
+
throw new VideoError({
|
|
118
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
119
|
+
message: `Runway submit failed: ${response.status} — ${sanitizeForLog(raw, 500)}`,
|
|
120
|
+
category: retriable ? ErrorCategory.NETWORK : ErrorCategory.EXECUTION,
|
|
121
|
+
severity: ErrorSeverity.HIGH,
|
|
122
|
+
retriable,
|
|
123
|
+
context: { status: response.status },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const json = (await response.json());
|
|
127
|
+
if (!json.id) {
|
|
128
|
+
throw new VideoError({
|
|
129
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
130
|
+
message: "Runway submit response missing id",
|
|
131
|
+
category: ErrorCategory.EXECUTION,
|
|
132
|
+
severity: ErrorSeverity.HIGH,
|
|
133
|
+
retriable: false,
|
|
134
|
+
context: { response: json },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return json.id;
|
|
138
|
+
}
|
|
139
|
+
async pollUntilComplete(taskId, abortSignal) {
|
|
140
|
+
const startTime = Date.now();
|
|
141
|
+
while (Date.now() - startTime < TOTAL_TIMEOUT_MS) {
|
|
142
|
+
if (abortSignal?.aborted) {
|
|
143
|
+
throw new VideoError({
|
|
144
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
145
|
+
message: `Runway poll for task ${taskId} aborted by caller`,
|
|
146
|
+
category: ErrorCategory.NETWORK,
|
|
147
|
+
severity: ErrorSeverity.MEDIUM,
|
|
148
|
+
retriable: false,
|
|
149
|
+
context: { taskId },
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const response = await this.fetchWithTimeout(`${this.baseUrl}/tasks/${taskId}`, {
|
|
153
|
+
method: "GET",
|
|
154
|
+
headers: {
|
|
155
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
156
|
+
"X-Runway-Version": this.apiVersion,
|
|
157
|
+
},
|
|
158
|
+
}, abortSignal);
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
const raw = await response.text();
|
|
161
|
+
throw new VideoError({
|
|
162
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
163
|
+
message: `Runway poll failed: ${response.status} — ${sanitizeForLog(raw, 500)}`,
|
|
164
|
+
category: ErrorCategory.NETWORK,
|
|
165
|
+
severity: ErrorSeverity.MEDIUM,
|
|
166
|
+
retriable: response.status >= 500,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const data = (await response.json());
|
|
170
|
+
if (data.status === "SUCCEEDED" || data.status === "succeeded") {
|
|
171
|
+
const url = Array.isArray(data.output) ? data.output[0] : data.output;
|
|
172
|
+
if (typeof url !== "string") {
|
|
173
|
+
throw new VideoError({
|
|
174
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
175
|
+
message: `Runway task ${taskId} completed but no output URL`,
|
|
176
|
+
category: ErrorCategory.EXECUTION,
|
|
177
|
+
severity: ErrorSeverity.HIGH,
|
|
178
|
+
retriable: false,
|
|
179
|
+
context: { taskId, data },
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return url;
|
|
183
|
+
}
|
|
184
|
+
if (data.status === "FAILED" || data.status === "failed") {
|
|
185
|
+
throw new VideoError({
|
|
186
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
187
|
+
message: `Runway task ${taskId} failed: ${data.failure ?? data.error ?? "unknown"}`,
|
|
188
|
+
category: ErrorCategory.EXECUTION,
|
|
189
|
+
severity: ErrorSeverity.HIGH,
|
|
190
|
+
retriable: false,
|
|
191
|
+
context: { taskId, data },
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
// Abortable sleep.
|
|
195
|
+
await new Promise((resolve, reject) => {
|
|
196
|
+
const onAbort = () => {
|
|
197
|
+
clearTimeout(timer);
|
|
198
|
+
reject(new VideoError({
|
|
199
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
200
|
+
message: `Runway poll for task ${taskId} aborted by caller`,
|
|
201
|
+
category: ErrorCategory.NETWORK,
|
|
202
|
+
severity: ErrorSeverity.MEDIUM,
|
|
203
|
+
retriable: false,
|
|
204
|
+
context: { taskId },
|
|
205
|
+
}));
|
|
206
|
+
};
|
|
207
|
+
const timer = setTimeout(() => {
|
|
208
|
+
abortSignal?.removeEventListener("abort", onAbort);
|
|
209
|
+
resolve();
|
|
210
|
+
}, POLL_INTERVAL_MS);
|
|
211
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
throw new VideoError({
|
|
215
|
+
code: VIDEO_ERROR_CODES.POLL_TIMEOUT,
|
|
216
|
+
message: `Runway task ${taskId} did not complete within ${TOTAL_TIMEOUT_MS / 1000}s`,
|
|
217
|
+
category: ErrorCategory.TIMEOUT,
|
|
218
|
+
severity: ErrorSeverity.MEDIUM,
|
|
219
|
+
retriable: true,
|
|
220
|
+
context: { taskId },
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async downloadVideo(url) {
|
|
224
|
+
try {
|
|
225
|
+
return await safeDownload(url, {
|
|
226
|
+
maxBytes: MAX_VIDEO_BYTES,
|
|
227
|
+
label: "Runway video",
|
|
228
|
+
timeoutMs: REQUEST_TIMEOUT_MS,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
throw new VideoError({
|
|
233
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
234
|
+
message: `Runway video download rejected: ${err instanceof Error ? err.message : String(err)}`,
|
|
235
|
+
category: ErrorCategory.NETWORK,
|
|
236
|
+
severity: ErrorSeverity.HIGH,
|
|
237
|
+
retriable: false,
|
|
238
|
+
context: { url },
|
|
239
|
+
originalError: err instanceof Error ? err : undefined,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async fetchWithTimeout(url, init, callerAbortSignal) {
|
|
244
|
+
const controller = new AbortController();
|
|
245
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
246
|
+
const onCallerAbort = () => controller.abort();
|
|
247
|
+
callerAbortSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
248
|
+
try {
|
|
249
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
253
|
+
throw new VideoError({
|
|
254
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
255
|
+
message: `Runway request to ${url} timed out after ${REQUEST_TIMEOUT_MS / 1000}s`,
|
|
256
|
+
category: ErrorCategory.NETWORK,
|
|
257
|
+
severity: ErrorSeverity.HIGH,
|
|
258
|
+
retriable: true,
|
|
259
|
+
originalError: err,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
throw new VideoError({
|
|
263
|
+
code: VIDEO_ERROR_CODES.GENERATION_FAILED,
|
|
264
|
+
message: `Runway fetch failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
265
|
+
category: ErrorCategory.NETWORK,
|
|
266
|
+
severity: ErrorSeverity.HIGH,
|
|
267
|
+
retriable: true,
|
|
268
|
+
originalError: err instanceof Error ? err : undefined,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
callerAbortSignal?.removeEventListener("abort", onCallerAbort);
|
|
273
|
+
clearTimeout(timeoutId);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
detectImageType(buffer) {
|
|
277
|
+
if (buffer.length < 4) {
|
|
278
|
+
return "jpeg";
|
|
279
|
+
}
|
|
280
|
+
if (buffer[0] === 0x89 && buffer[1] === 0x50) {
|
|
281
|
+
return "png";
|
|
282
|
+
}
|
|
283
|
+
if (buffer[0] === 0xff && buffer[1] === 0xd8) {
|
|
284
|
+
return "jpeg";
|
|
285
|
+
}
|
|
286
|
+
// RIFF container: check offset 8 to distinguish WebP from WAV so audio
|
|
287
|
+
// data passed as image is not silently misidentified as WebP.
|
|
288
|
+
if (buffer.length >= 12 &&
|
|
289
|
+
buffer[0] === 0x52 &&
|
|
290
|
+
buffer[1] === 0x49 &&
|
|
291
|
+
buffer[2] === 0x46 &&
|
|
292
|
+
buffer[3] === 0x46) {
|
|
293
|
+
if (buffer[8] === 0x57 &&
|
|
294
|
+
buffer[9] === 0x45 &&
|
|
295
|
+
buffer[10] === 0x42 &&
|
|
296
|
+
buffer[11] === 0x50) {
|
|
297
|
+
return "webp";
|
|
298
|
+
}
|
|
299
|
+
// RIFF but not WEBP (e.g. WAVE audio) — not a valid image.
|
|
300
|
+
return "jpeg";
|
|
301
|
+
}
|
|
302
|
+
return "jpeg";
|
|
303
|
+
}
|
|
304
|
+
calculateDimensions(options) {
|
|
305
|
+
const aspectRatio = options.aspectRatio ?? "16:9";
|
|
306
|
+
const resolution = options.resolution ?? "720p";
|
|
307
|
+
if (resolution === "1080p") {
|
|
308
|
+
return aspectRatio === "9:16"
|
|
309
|
+
? { width: 1080, height: 1920 }
|
|
310
|
+
: { width: 1920, height: 1080 };
|
|
311
|
+
}
|
|
312
|
+
return aspectRatio === "9:16"
|
|
313
|
+
? { width: 720, height: 1280 }
|
|
314
|
+
: { width: 1280, height: 720 };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -95,7 +95,25 @@ export declare function generateVideoWithVertex(image: Buffer, prompt: string, o
|
|
|
95
95
|
* @throws {VideoError} When API returns an error or polling times out
|
|
96
96
|
*/
|
|
97
97
|
export declare function generateTransitionWithVertex(firstFrame: Buffer, lastFrame: Buffer, prompt: string, options?: {
|
|
98
|
-
aspectRatio?: "9:16" | "16:9";
|
|
98
|
+
aspectRatio?: "9:16" | "16:9" | "1:1" | string;
|
|
99
99
|
resolution?: "720p" | "1080p";
|
|
100
100
|
audio?: boolean;
|
|
101
101
|
}, durationSeconds?: 4 | 6 | 8, region?: string): Promise<Buffer>;
|
|
102
|
+
import type { VideoHandler, VideoTransitionOptions } from "../../types/index.js";
|
|
103
|
+
/**
|
|
104
|
+
* Class wrapper around the standalone Vertex Veo functions, conforming to
|
|
105
|
+
* the `VideoHandler` contract so it can register with `VideoProcessor`.
|
|
106
|
+
*
|
|
107
|
+
* The free functions (`generateVideoWithVertex`, `generateTransitionWithVertex`,
|
|
108
|
+
* `isVertexVideoConfigured`) are kept exported for backward compatibility —
|
|
109
|
+
* external callers (Director's `directorPipeline.ts`, test scripts) reference
|
|
110
|
+
* them directly.
|
|
111
|
+
*/
|
|
112
|
+
export declare class VertexVideoHandler implements VideoHandler {
|
|
113
|
+
readonly maxDurationSeconds = 8;
|
|
114
|
+
readonly supportedAspectRatios: readonly ("9:16" | "16:9")[];
|
|
115
|
+
readonly supportedResolutions: readonly ("720p" | "1080p")[];
|
|
116
|
+
isConfigured(): boolean;
|
|
117
|
+
generate(image: Buffer, prompt: string, options: VideoOutputOptions, region?: string): Promise<VideoGenerationResult>;
|
|
118
|
+
generateTransition(firstFrame: Buffer, lastFrame: Buffer, prompt: string, options?: VideoTransitionOptions, region?: string): Promise<Buffer>;
|
|
119
|
+
}
|
|
@@ -609,15 +609,6 @@ async function pollVideoOperation(operationName, accessToken, project, location,
|
|
|
609
609
|
* @throws {VideoError} When API returns an error or polling times out
|
|
610
610
|
*/
|
|
611
611
|
export async function generateTransitionWithVertex(firstFrame, lastFrame, prompt, options = {}, durationSeconds = 4, region) {
|
|
612
|
-
if (!isVertexVideoConfigured()) {
|
|
613
|
-
throw new VideoError({
|
|
614
|
-
code: VIDEO_ERROR_CODES.PROVIDER_NOT_CONFIGURED,
|
|
615
|
-
message: "Vertex AI credentials not configured for transition generation.",
|
|
616
|
-
category: ErrorCategory.CONFIGURATION,
|
|
617
|
-
severity: ErrorSeverity.HIGH,
|
|
618
|
-
retriable: false,
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
612
|
const config = await getVertexConfig();
|
|
622
613
|
const project = config.project;
|
|
623
614
|
const location = region || config.location;
|
|
@@ -774,3 +765,36 @@ async function pollOperation(modelOrEndpoint, operationName, accessToken, projec
|
|
|
774
765
|
async function pollTransitionOperation(operationName, accessToken, project, location, timeoutMs) {
|
|
775
766
|
return pollOperation(VEO_FAST_MODEL, operationName, accessToken, project, location, timeoutMs);
|
|
776
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Class wrapper around the standalone Vertex Veo functions, conforming to
|
|
770
|
+
* the `VideoHandler` contract so it can register with `VideoProcessor`.
|
|
771
|
+
*
|
|
772
|
+
* The free functions (`generateVideoWithVertex`, `generateTransitionWithVertex`,
|
|
773
|
+
* `isVertexVideoConfigured`) are kept exported for backward compatibility —
|
|
774
|
+
* external callers (Director's `directorPipeline.ts`, test scripts) reference
|
|
775
|
+
* them directly.
|
|
776
|
+
*/
|
|
777
|
+
export class VertexVideoHandler {
|
|
778
|
+
maxDurationSeconds = 8;
|
|
779
|
+
supportedAspectRatios = [
|
|
780
|
+
"9:16",
|
|
781
|
+
"16:9",
|
|
782
|
+
];
|
|
783
|
+
supportedResolutions = [
|
|
784
|
+
"720p",
|
|
785
|
+
"1080p",
|
|
786
|
+
];
|
|
787
|
+
isConfigured() {
|
|
788
|
+
return isVertexVideoConfigured();
|
|
789
|
+
}
|
|
790
|
+
generate(image, prompt, options, region) {
|
|
791
|
+
return generateVideoWithVertex(image, prompt, options, region);
|
|
792
|
+
}
|
|
793
|
+
generateTransition(firstFrame, lastFrame, prompt, options, region) {
|
|
794
|
+
return generateTransitionWithVertex(firstFrame, lastFrame, prompt, {
|
|
795
|
+
aspectRatio: options?.aspectRatio,
|
|
796
|
+
resolution: options?.resolution,
|
|
797
|
+
audio: options?.audio,
|
|
798
|
+
}, options?.durationSeconds ?? 4, region);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
@@ -547,9 +547,16 @@ export const directAgentTools = {
|
|
|
547
547
|
// It is only included in directAgentTools when NEUROLINK_ENABLE_BASH_TOOL=true or
|
|
548
548
|
// toolConfig.enableBashTool is explicitly set to true. See shouldEnableBashTool() in toolUtils.ts.
|
|
549
549
|
websearchGrounding: tool({
|
|
550
|
-
description: "Search
|
|
550
|
+
description: "Performs a Google Search and returns a summarized answer with source citations. Always check the current date before constructing the query. Use whenever the answer depends on time-sensitive facts or requires verification against real-world sources.",
|
|
551
551
|
inputSchema: z.object({
|
|
552
|
-
query: z
|
|
552
|
+
query: z
|
|
553
|
+
.string()
|
|
554
|
+
.trim()
|
|
555
|
+
.min(1, { message: "must be a non-empty search string" })
|
|
556
|
+
.refine((v) => v.toLowerCase() !== "undefined", {
|
|
557
|
+
message: 'must not be the literal string "undefined" — pass a real search query',
|
|
558
|
+
})
|
|
559
|
+
.describe("The search query string to look up on the web."),
|
|
553
560
|
maxResults: z
|
|
554
561
|
.number()
|
|
555
562
|
.optional()
|
|
@@ -581,7 +588,8 @@ export const directAgentTools = {
|
|
|
581
588
|
project: hasProjectId,
|
|
582
589
|
location: projectLocation,
|
|
583
590
|
});
|
|
584
|
-
const websearchModel =
|
|
591
|
+
const websearchModel = process.env.NEUROLINK_WEBSEARCH_MODEL?.trim() ||
|
|
592
|
+
"gemini-2.5-flash-lite";
|
|
585
593
|
const model = vertex_ai.getGenerativeModel({
|
|
586
594
|
model: websearchModel,
|
|
587
595
|
tools: createGoogleSearchTools(),
|
|
@@ -14,10 +14,16 @@ export class ExperimentRunner {
|
|
|
14
14
|
/** Runs the experiment with hard timeout, returns summary */
|
|
15
15
|
async run() {
|
|
16
16
|
const logPath = path.join(this.config.repoPath, this.config.logPath);
|
|
17
|
-
// Redact potential inline env vars or tokens before logging
|
|
17
|
+
// Redact potential inline env vars or tokens before logging.
|
|
18
|
+
// sanitizeForLog handles in-string `Bearer`/`Token`/`sk-` patterns but
|
|
19
|
+
// not CLI flag forms like `--token foo` (which is a different shape —
|
|
20
|
+
// separate argv tokens rather than concatenated values). The flag-form
|
|
21
|
+
// redactor below is narrowly scoped; not the H04 anti-pattern.
|
|
18
22
|
const redactedCmd = this.config.runCommand
|
|
19
23
|
.replace(/[A-Z_]+=\S+\s/g, (m) => m.split("=")[0] + "=*** ")
|
|
20
|
-
.replace(
|
|
24
|
+
.replace(
|
|
25
|
+
// eslint-disable-next-line neurolink/no-inline-secret-regex -- narrowly-scoped CLI-flag redactor
|
|
26
|
+
/--(?:token|key|secret|password)\s+\S+/gi, (m) => m.split(/\s+/)[0] + " ***");
|
|
21
27
|
logger.info("[Autoresearch] Starting experiment", {
|
|
22
28
|
command: redactedCmd,
|
|
23
29
|
timeoutMs: this.config.timeoutMs,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar Module — Talking-Head / Lip-sync Integration for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* Provides avatar-generation capability across providers (D-ID, HeyGen,
|
|
5
|
+
* Replicate-hosted MuseTalk / SadTalker / Wav2Lip).
|
|
6
|
+
*
|
|
7
|
+
* Use `AvatarProcessor.generate(provider, options)` to dispatch to the
|
|
8
|
+
* registered handler for `provider`.
|
|
9
|
+
*
|
|
10
|
+
* @module avatar
|
|
11
|
+
*/
|
|
12
|
+
export { AVATAR_ERROR_CODES, AvatarError, AvatarProcessor, } from "../utils/avatarProcessor.js";
|
|
13
|
+
export { DIDAvatar, DIDAvatar as DIDAvatarHandler, } from "./providers/DIDAvatar.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar Module — Talking-Head / Lip-sync Integration for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* Provides avatar-generation capability across providers (D-ID, HeyGen,
|
|
5
|
+
* Replicate-hosted MuseTalk / SadTalker / Wav2Lip).
|
|
6
|
+
*
|
|
7
|
+
* Use `AvatarProcessor.generate(provider, options)` to dispatch to the
|
|
8
|
+
* registered handler for `provider`.
|
|
9
|
+
*
|
|
10
|
+
* @module avatar
|
|
11
|
+
*/
|
|
12
|
+
export { AVATAR_ERROR_CODES, AvatarError, AvatarProcessor, } from "../utils/avatarProcessor.js";
|
|
13
|
+
export { DIDAvatar, DIDAvatar as DIDAvatarHandler, } from "./providers/DIDAvatar.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D-ID Avatar / Lip-sync Handler
|
|
3
|
+
*
|
|
4
|
+
* Async talking-head generation. Submits a /talks request with a source
|
|
5
|
+
* image and either an audio URL or a text+voice script, polls the talk
|
|
6
|
+
* status, and downloads the resulting MP4.
|
|
7
|
+
*
|
|
8
|
+
* @module avatar/providers/DIDAvatar
|
|
9
|
+
* @see https://docs.d-id.com/reference/talks-overview
|
|
10
|
+
*/
|
|
11
|
+
import type { AvatarHandler, AvatarOptions, AvatarResult, AvatarVideoFormat } from "../../types/index.js";
|
|
12
|
+
/**
|
|
13
|
+
* D-ID Avatar Handler.
|
|
14
|
+
*
|
|
15
|
+
* Auth: `Authorization: Basic ${DID_API_KEY}` (the API key is
|
|
16
|
+
* already a base64-encoded `username:password` from the D-ID console).
|
|
17
|
+
*
|
|
18
|
+
* Env vars: `DID_API_KEY` (preferred) / `D_ID_API_KEY` (legacy alias).
|
|
19
|
+
*/
|
|
20
|
+
export declare class DIDAvatar implements AvatarHandler {
|
|
21
|
+
readonly maxAudioDurationSeconds = 60;
|
|
22
|
+
readonly supportedFormats: readonly AvatarVideoFormat[];
|
|
23
|
+
private readonly apiKey;
|
|
24
|
+
private readonly baseUrl;
|
|
25
|
+
constructor(apiKey?: string);
|
|
26
|
+
isConfigured(): boolean;
|
|
27
|
+
generate(options: AvatarOptions): Promise<AvatarResult>;
|
|
28
|
+
private uploadImage;
|
|
29
|
+
private uploadAudio;
|
|
30
|
+
private submitTalk;
|
|
31
|
+
private pollUntilDone;
|
|
32
|
+
private downloadResult;
|
|
33
|
+
private resolveBuffer;
|
|
34
|
+
private detectImageMime;
|
|
35
|
+
/**
|
|
36
|
+
* Detect the audio subtype from magic bytes.
|
|
37
|
+
*
|
|
38
|
+
* Recognised formats:
|
|
39
|
+
* - WAV : RIFF header (52 49 46 46)
|
|
40
|
+
* - OGG : OggS capture (4F 67 67 53)
|
|
41
|
+
* - MP3 : ID3 tag (49 44 33) or MPEG sync word (FF Ex)
|
|
42
|
+
* - M4A : "ftyp" box at offset 4 (ISO base media / M4A)
|
|
43
|
+
*
|
|
44
|
+
* Falls back to "mp3" when detection is inconclusive.
|
|
45
|
+
*/
|
|
46
|
+
private detectAudioType;
|
|
47
|
+
private fetchWithTimeout;
|
|
48
|
+
private assertOk;
|
|
49
|
+
}
|