vidspotai-shared 1.0.94 → 1.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/lib/globals/aiModels/enums.d.ts +2 -0
  2. package/lib/globals/aiModels/enums.d.ts.map +1 -1
  3. package/lib/globals/aiModels/enums.js +5 -0
  4. package/lib/globals/aiModels/index.d.ts.map +1 -1
  5. package/lib/globals/aiModels/index.js +2 -0
  6. package/lib/globals/aiModels/providers/hostedAvatars.d.ts +22 -0
  7. package/lib/globals/aiModels/providers/hostedAvatars.d.ts.map +1 -0
  8. package/lib/globals/aiModels/providers/hostedAvatars.js +129 -0
  9. package/lib/globals/types.d.ts +58 -1
  10. package/lib/globals/types.d.ts.map +1 -1
  11. package/lib/globals/types.js +61 -1
  12. package/lib/models/demoVideoProject.model.d.ts +244 -0
  13. package/lib/models/demoVideoProject.model.d.ts.map +1 -0
  14. package/lib/models/demoVideoProject.model.js +2 -0
  15. package/lib/models/githubConnection.model.d.ts +35 -0
  16. package/lib/models/githubConnection.model.d.ts.map +1 -0
  17. package/lib/models/githubConnection.model.js +2 -0
  18. package/lib/models/index.d.ts +3 -0
  19. package/lib/models/index.d.ts.map +1 -1
  20. package/lib/models/index.js +3 -0
  21. package/lib/models/outreach.model.d.ts +175 -0
  22. package/lib/models/outreach.model.d.ts.map +1 -0
  23. package/lib/models/outreach.model.js +2 -0
  24. package/lib/models/video.model.d.ts +4 -0
  25. package/lib/models/video.model.d.ts.map +1 -1
  26. package/lib/schemas/brandKit.schema.d.ts +4 -0
  27. package/lib/schemas/brandKit.schema.d.ts.map +1 -1
  28. package/lib/schemas/brandKit.schema.js +10 -0
  29. package/lib/schemas/demoQuestion.schema.d.ts +286 -0
  30. package/lib/schemas/demoQuestion.schema.d.ts.map +1 -0
  31. package/lib/schemas/demoQuestion.schema.js +210 -0
  32. package/lib/schemas/demoSpec.schema.d.ts +109 -6
  33. package/lib/schemas/demoSpec.schema.d.ts.map +1 -1
  34. package/lib/schemas/demoSpec.schema.js +95 -7
  35. package/lib/schemas/index.d.ts +1 -0
  36. package/lib/schemas/index.d.ts.map +1 -1
  37. package/lib/schemas/index.js +1 -0
  38. package/lib/schemas/videoPlan.schema.d.ts +2 -2
  39. package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
  40. package/lib/schemas/videoPlan.schema.js +11 -1
  41. package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
  42. package/lib/services/agent/providerFallback/chains.js +9 -1
  43. package/lib/services/agent/taskPoller.d.ts.map +1 -1
  44. package/lib/services/agent/taskPoller.js +17 -6
  45. package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +21 -9
  46. package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
  47. package/lib/services/agent/tools/generateAvatarVideo.tool.js +135 -39
  48. package/lib/services/agent/tools/planVideo.tool.d.ts +2 -2
  49. package/lib/services/aiGen/aiGenFactory.service.d.ts +1 -1
  50. package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
  51. package/lib/services/aiGen/aiGenFactory.service.js +10 -2
  52. package/lib/services/aiGen/helpers.d.ts.map +1 -1
  53. package/lib/services/aiGen/helpers.js +12 -2
  54. package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
  55. package/lib/services/aiGen/providers/kling/kling.service.js +47 -8
  56. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts +8 -0
  57. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
  58. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +55 -2
  59. package/lib/services/avatarGen/IAvatarVideoProvider.d.ts +136 -0
  60. package/lib/services/avatarGen/IAvatarVideoProvider.d.ts.map +1 -0
  61. package/lib/services/avatarGen/IAvatarVideoProvider.js +42 -0
  62. package/lib/services/avatarGen/avatarProviderFactory.d.ts +18 -0
  63. package/lib/services/avatarGen/avatarProviderFactory.d.ts.map +1 -0
  64. package/lib/services/avatarGen/avatarProviderFactory.js +54 -0
  65. package/lib/services/avatarGen/index.d.ts +6 -0
  66. package/lib/services/avatarGen/index.d.ts.map +1 -0
  67. package/lib/services/avatarGen/index.js +21 -0
  68. package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts +45 -0
  69. package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts.map +1 -0
  70. package/lib/services/avatarGen/providers/heygenAvatarProvider.js +190 -0
  71. package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts +32 -0
  72. package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts.map +1 -0
  73. package/lib/services/avatarGen/providers/klingAvatarProvider.js +69 -0
  74. package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts +56 -0
  75. package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts.map +1 -0
  76. package/lib/services/avatarGen/providers/tavusAvatarProvider.js +183 -0
  77. package/lib/services/demo/demoAuthor.d.ts +45 -0
  78. package/lib/services/demo/demoAuthor.d.ts.map +1 -0
  79. package/lib/services/demo/demoAuthor.js +75 -0
  80. package/lib/services/demo/demoAuthorNormalize.d.ts +49 -0
  81. package/lib/services/demo/demoAuthorNormalize.d.ts.map +1 -0
  82. package/lib/services/demo/demoAuthorNormalize.js +327 -0
  83. package/lib/services/demo/demoAuthorPrompt.d.ts +102 -0
  84. package/lib/services/demo/demoAuthorPrompt.d.ts.map +1 -0
  85. package/lib/services/demo/demoAuthorPrompt.js +243 -0
  86. package/lib/services/demo/demoCredits.d.ts +20 -0
  87. package/lib/services/demo/demoCredits.d.ts.map +1 -0
  88. package/lib/services/demo/demoCredits.js +51 -0
  89. package/lib/services/demo/demoMediaGuard.d.ts +43 -0
  90. package/lib/services/demo/demoMediaGuard.d.ts.map +1 -0
  91. package/lib/services/demo/demoMediaGuard.js +207 -0
  92. package/lib/services/demo/demoMusic.d.ts +13 -0
  93. package/lib/services/demo/demoMusic.d.ts.map +1 -0
  94. package/lib/services/demo/demoMusic.js +93 -0
  95. package/lib/services/demo/demoPrefill.d.ts +76 -0
  96. package/lib/services/demo/demoPrefill.d.ts.map +1 -0
  97. package/lib/services/demo/demoPrefill.js +435 -0
  98. package/lib/services/demo/demoRevisePrompt.d.ts +17 -0
  99. package/lib/services/demo/demoRevisePrompt.d.ts.map +1 -0
  100. package/lib/services/demo/demoRevisePrompt.js +85 -0
  101. package/lib/services/demo/demoReviser.d.ts +63 -0
  102. package/lib/services/demo/demoReviser.d.ts.map +1 -0
  103. package/lib/services/demo/demoReviser.js +81 -0
  104. package/lib/services/demo/demoScriptPrompt.d.ts +63 -0
  105. package/lib/services/demo/demoScriptPrompt.d.ts.map +1 -0
  106. package/lib/services/demo/demoScriptPrompt.js +234 -0
  107. package/lib/services/demo/demoScriptWriter.d.ts +65 -0
  108. package/lib/services/demo/demoScriptWriter.d.ts.map +1 -0
  109. package/lib/services/demo/demoScriptWriter.js +211 -0
  110. package/lib/services/demo/demoTriage.d.ts +65 -0
  111. package/lib/services/demo/demoTriage.d.ts.map +1 -0
  112. package/lib/services/demo/demoTriage.js +130 -0
  113. package/lib/services/demo/githubOAuth.d.ts +78 -0
  114. package/lib/services/demo/githubOAuth.d.ts.map +1 -0
  115. package/lib/services/demo/githubOAuth.js +209 -0
  116. package/lib/services/demo/githubOAuthState.d.ts +10 -0
  117. package/lib/services/demo/githubOAuthState.d.ts.map +1 -0
  118. package/lib/services/demo/githubOAuthState.js +63 -0
  119. package/lib/services/demo/index.d.ts +24 -0
  120. package/lib/services/demo/index.d.ts.map +1 -0
  121. package/lib/services/demo/index.js +39 -0
  122. package/lib/services/firestore.service.d.ts +11 -0
  123. package/lib/services/firestore.service.d.ts.map +1 -1
  124. package/lib/services/firestore.service.js +24 -0
  125. package/lib/services/index.d.ts +2 -0
  126. package/lib/services/index.d.ts.map +1 -1
  127. package/lib/services/index.js +2 -0
  128. package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
  129. package/lib/services/tts/providers/elevenlabs.service.js +16 -8
  130. package/lib/utils/index.d.ts +1 -0
  131. package/lib/utils/index.d.ts.map +1 -1
  132. package/lib/utils/index.js +1 -0
  133. package/lib/utils/outreachTemplate.d.ts +46 -0
  134. package/lib/utils/outreachTemplate.d.ts.map +1 -0
  135. package/lib/utils/outreachTemplate.js +174 -0
  136. package/package.json +1 -1
@@ -0,0 +1,136 @@
1
+ import { EVideoSceneStatus, TVideoJobTask } from "../../globals/types";
2
+ import { EVideoMode } from "../aiGen/types";
3
+ /**
4
+ * Avatar video generation — a first-class provider abstraction, deliberately
5
+ * SEPARATE from the generic `BaseAiGenProviderService` (text/image → video).
6
+ *
7
+ * Why its own seam (SOLID):
8
+ * - SRP: animating a presenter/script into a talking video is a different
9
+ * responsibility from text/image→video generation. Each gets its own contract.
10
+ * - ISP: avatar engines have different capabilities (hosted avatar catalogs,
11
+ * trained replicas, dubbing). Those are NARROW optional interfaces below, so
12
+ * no engine has to no-op methods it doesn't support.
13
+ * - DIP: the worker's `AvatarJobProcessor` and the agent's avatar tool depend on
14
+ * THIS interface, not on any concrete engine (Kling/HeyGen/Tavus).
15
+ * - OCP: adding an engine = add a class + register it in the avatar factory,
16
+ * with zero edits to the processor.
17
+ *
18
+ * Today `kling-avatar` is the only implementation (it adapts the shared Kling
19
+ * transport via `KlingAvatarProvider`). HeyGen/Tavus/Synthesia plug in here next.
20
+ */
21
+ export declare enum EAvatarEngine {
22
+ KLING = "kling",
23
+ HEYGEN = "heygen",
24
+ TAVUS = "tavus",
25
+ SYNTHESIA = "synthesia"
26
+ }
27
+ /**
28
+ * Declares HOW an engine produces a talking video, so the orchestrator
29
+ * (AvatarJobProcessor) knows what to do around the call:
30
+ * - inputMode "byo-media": caller supplies a face image; the AUDIO is produced
31
+ * by us (TTS stays its own concern) and passed in. (Kling)
32
+ * - inputMode "hosted": caller supplies a provider-hosted avatar + voice + a
33
+ * script; the engine does its own TTS/lip-sync. (HeyGen/Tavus)
34
+ * - nativeTts: false => the processor must run TTS first and pass `audioUrl`.
35
+ * - multiSceneSplit: true => long audio is split into scenes + stitched (Kling);
36
+ * false => the engine renders the whole script in one shot (HeyGen/Tavus).
37
+ */
38
+ export interface AvatarCapabilities {
39
+ inputMode: "byo-media" | "hosted";
40
+ nativeTts: boolean;
41
+ multiSceneSplit: boolean;
42
+ }
43
+ /**
44
+ * Discriminated request. A provider accepts exactly one `mode` (the one its
45
+ * `capabilities.inputMode` declares); passing the other is a programmer error
46
+ * and providers throw.
47
+ */
48
+ export type AvatarGenerateRequest = {
49
+ mode: "byo-media";
50
+ /** Presenter face still — the engine animates this image to lipsync the audio. */
51
+ faceImageUrl: string;
52
+ /** Public audio URL (we generated it via TTS, or the caller supplied it). */
53
+ audioUrl: string;
54
+ /** Optional motion/emotion hint passed through to the engine. */
55
+ prompt?: string;
56
+ /** std / pro etc. — maps to the engine's render quality mode. */
57
+ renderMode?: EVideoMode;
58
+ } | {
59
+ mode: "hosted";
60
+ /** Provider-hosted avatar id (or trained replica id). */
61
+ hostedAvatarId: string;
62
+ /** Provider-hosted voice id. */
63
+ hostedVoiceId: string;
64
+ /** Script the engine will synthesize + lipsync natively. */
65
+ script: string;
66
+ /** BCP-47 locale for native TTS / dubbing. */
67
+ locale?: string;
68
+ renderMode?: EVideoMode;
69
+ };
70
+ export interface AvatarSubmitResult {
71
+ /** Provider-internal task id, polled via `checkStatus`. */
72
+ providerTaskId: TVideoJobTask;
73
+ }
74
+ export interface AvatarStatusQuery {
75
+ providerTaskId: TVideoJobTask;
76
+ /** Filename (no extension) used when stashing the finished video to storage. */
77
+ outputFilename: string;
78
+ /** Storage sub-path; defaults to the avatar bucket folder. */
79
+ outputFilePath?: string;
80
+ }
81
+ export interface AvatarStatusResult {
82
+ status: EVideoSceneStatus;
83
+ /** Present when status is COMPLETED. */
84
+ videoUrl?: string;
85
+ /** Present when status is FAILED. */
86
+ errorMessage?: string;
87
+ }
88
+ /**
89
+ * Core contract every avatar engine implements. Submit + poll only — TTS,
90
+ * scene-splitting, stitching, credits and retries live in the orchestrator.
91
+ */
92
+ export interface IAvatarVideoProvider {
93
+ readonly engine: EAvatarEngine;
94
+ readonly capabilities: AvatarCapabilities;
95
+ generate(req: AvatarGenerateRequest): Promise<AvatarSubmitResult>;
96
+ checkStatus(query: AvatarStatusQuery): Promise<AvatarStatusResult>;
97
+ }
98
+ export interface AvatarOption {
99
+ id: string;
100
+ name: string;
101
+ previewUrl?: string;
102
+ }
103
+ export interface VoiceOption {
104
+ id: string;
105
+ name: string;
106
+ gender?: "male" | "female" | "neutral";
107
+ accent?: string;
108
+ previewUrl?: string;
109
+ }
110
+ export interface ConsentRecord {
111
+ /** Who consented (user id). */
112
+ userId: string;
113
+ /** Free-text or signed consent reference for likeness training. */
114
+ statement: string;
115
+ /** ISO timestamp the consent was captured. */
116
+ capturedAt: string;
117
+ }
118
+ /** Engine exposes a catalog of hosted avatars/voices (HeyGen, Tavus, Synthesia). */
119
+ export interface ISupportsHostedCatalog {
120
+ listAvatars(): Promise<AvatarOption[]>;
121
+ listVoices(): Promise<VoiceOption[]>;
122
+ }
123
+ /** Engine can train a likeness replica from user media (HeyGen instant avatar, Tavus replica). */
124
+ export interface ISupportsReplica {
125
+ createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<{
126
+ replicaId: string;
127
+ }>;
128
+ }
129
+ /** Engine can dub an existing video into another language (Tavus — our multilingual wedge). */
130
+ export interface ISupportsDubbing {
131
+ dub(videoUrl: string, targetLocale: string): Promise<AvatarSubmitResult>;
132
+ }
133
+ export declare function supportsHostedCatalog(p: IAvatarVideoProvider): p is IAvatarVideoProvider & ISupportsHostedCatalog;
134
+ export declare function supportsReplica(p: IAvatarVideoProvider): p is IAvatarVideoProvider & ISupportsReplica;
135
+ export declare function supportsDubbing(p: IAvatarVideoProvider): p is IAvatarVideoProvider & ISupportsDubbing;
136
+ //# sourceMappingURL=IAvatarVideoProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IAvatarVideoProvider.d.ts","sourceRoot":"","sources":["../../../src/services/avatarGen/IAvatarVideoProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EAvatarEngine = void 0;
4
+ exports.supportsHostedCatalog = supportsHostedCatalog;
5
+ exports.supportsReplica = supportsReplica;
6
+ exports.supportsDubbing = supportsDubbing;
7
+ /**
8
+ * Avatar video generation — a first-class provider abstraction, deliberately
9
+ * SEPARATE from the generic `BaseAiGenProviderService` (text/image → video).
10
+ *
11
+ * Why its own seam (SOLID):
12
+ * - SRP: animating a presenter/script into a talking video is a different
13
+ * responsibility from text/image→video generation. Each gets its own contract.
14
+ * - ISP: avatar engines have different capabilities (hosted avatar catalogs,
15
+ * trained replicas, dubbing). Those are NARROW optional interfaces below, so
16
+ * no engine has to no-op methods it doesn't support.
17
+ * - DIP: the worker's `AvatarJobProcessor` and the agent's avatar tool depend on
18
+ * THIS interface, not on any concrete engine (Kling/HeyGen/Tavus).
19
+ * - OCP: adding an engine = add a class + register it in the avatar factory,
20
+ * with zero edits to the processor.
21
+ *
22
+ * Today `kling-avatar` is the only implementation (it adapts the shared Kling
23
+ * transport via `KlingAvatarProvider`). HeyGen/Tavus/Synthesia plug in here next.
24
+ */
25
+ var EAvatarEngine;
26
+ (function (EAvatarEngine) {
27
+ EAvatarEngine["KLING"] = "kling";
28
+ EAvatarEngine["HEYGEN"] = "heygen";
29
+ EAvatarEngine["TAVUS"] = "tavus";
30
+ EAvatarEngine["SYNTHESIA"] = "synthesia";
31
+ })(EAvatarEngine || (exports.EAvatarEngine = EAvatarEngine = {}));
32
+ // ─── Type guards ─────────────────────────────────────────────────────────────
33
+ function supportsHostedCatalog(p) {
34
+ return (typeof p.listAvatars === "function" &&
35
+ typeof p.listVoices === "function");
36
+ }
37
+ function supportsReplica(p) {
38
+ return typeof p.createReplica === "function";
39
+ }
40
+ function supportsDubbing(p) {
41
+ return typeof p.dub === "function";
42
+ }
@@ -0,0 +1,18 @@
1
+ import { EVideoGenModels } from "../../globals/aiModels";
2
+ import { AvatarCapabilities, IAvatarVideoProvider } from "./IAvatarVideoProvider";
3
+ /** True if `modelKey` is an avatar model handled by a dedicated avatar provider. */
4
+ export declare function isAvatarModel(modelKey: EVideoGenModels): boolean;
5
+ /** Capabilities for an avatar model, or undefined if it isn't an avatar model. */
6
+ export declare function getAvatarCapabilities(modelKey: EVideoGenModels): AvatarCapabilities | undefined;
7
+ /**
8
+ * True for "hosted" avatar engines (HeyGen/Tavus) — the engine owns TTS + lipsync
9
+ * from a script, so the orchestrator skips the byo-media (face image + audio)
10
+ * path. False for byo-media engines (Kling) and non-avatar models.
11
+ */
12
+ export declare function isHostedAvatarModel(modelKey: EVideoGenModels): boolean;
13
+ /**
14
+ * Resolve the avatar provider for a model key. Throws if the model isn't an
15
+ * avatar model (callers should gate on `isAvatarModel` or know the model type).
16
+ */
17
+ export declare function getAvatarVideoProvider(modelKey: EVideoGenModels): IAvatarVideoProvider;
18
+ //# sourceMappingURL=avatarProviderFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatarProviderFactory.d.ts","sourceRoot":"","sources":["../../../src/services/avatarGen/avatarProviderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AA4ClF,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAEhE;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,GACxB,kBAAkB,GAAG,SAAS,CAEhC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,GACxB,oBAAoB,CAMtB"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAvatarModel = isAvatarModel;
4
+ exports.getAvatarCapabilities = getAvatarCapabilities;
5
+ exports.isHostedAvatarModel = isHostedAvatarModel;
6
+ exports.getAvatarVideoProvider = getAvatarVideoProvider;
7
+ const aiModels_1 = require("../../globals/aiModels");
8
+ const heygenAvatarProvider_1 = require("./providers/heygenAvatarProvider");
9
+ const klingAvatarProvider_1 = require("./providers/klingAvatarProvider");
10
+ const tavusAvatarProvider_1 = require("./providers/tavusAvatarProvider");
11
+ const avatarProviderMap = {
12
+ [aiModels_1.EVideoGenModels.KLING_AVATAR]: (modelKey) => new klingAvatarProvider_1.KlingAvatarProvider(modelKey),
13
+ [aiModels_1.EVideoGenModels.HEYGEN_AVATAR]: (modelKey) => new heygenAvatarProvider_1.HeyGenAvatarProvider(modelKey),
14
+ [aiModels_1.EVideoGenModels.TAVUS_AVATAR]: (modelKey) => new tavusAvatarProvider_1.TavusAvatarProvider(modelKey),
15
+ };
16
+ /**
17
+ * Static capability lookup, keyed off each provider's `CAPABILITIES` constant —
18
+ * so orchestrators (the worker, controllers) can branch on input mode WITHOUT
19
+ * constructing a provider (construction needs the engine's API key, which would
20
+ * make a simple "is this hosted?" check fail when keys are absent). Single
21
+ * source of truth: each entry references the provider class's own static.
22
+ */
23
+ const avatarCapabilityMap = {
24
+ [aiModels_1.EVideoGenModels.KLING_AVATAR]: klingAvatarProvider_1.KlingAvatarProvider.CAPABILITIES,
25
+ [aiModels_1.EVideoGenModels.HEYGEN_AVATAR]: heygenAvatarProvider_1.HeyGenAvatarProvider.CAPABILITIES,
26
+ [aiModels_1.EVideoGenModels.TAVUS_AVATAR]: tavusAvatarProvider_1.TavusAvatarProvider.CAPABILITIES,
27
+ };
28
+ /** True if `modelKey` is an avatar model handled by a dedicated avatar provider. */
29
+ function isAvatarModel(modelKey) {
30
+ return modelKey in avatarProviderMap;
31
+ }
32
+ /** Capabilities for an avatar model, or undefined if it isn't an avatar model. */
33
+ function getAvatarCapabilities(modelKey) {
34
+ return avatarCapabilityMap[modelKey];
35
+ }
36
+ /**
37
+ * True for "hosted" avatar engines (HeyGen/Tavus) — the engine owns TTS + lipsync
38
+ * from a script, so the orchestrator skips the byo-media (face image + audio)
39
+ * path. False for byo-media engines (Kling) and non-avatar models.
40
+ */
41
+ function isHostedAvatarModel(modelKey) {
42
+ return avatarCapabilityMap[modelKey]?.inputMode === "hosted";
43
+ }
44
+ /**
45
+ * Resolve the avatar provider for a model key. Throws if the model isn't an
46
+ * avatar model (callers should gate on `isAvatarModel` or know the model type).
47
+ */
48
+ function getAvatarVideoProvider(modelKey) {
49
+ const factory = avatarProviderMap[modelKey];
50
+ if (!factory) {
51
+ throw new Error(`No avatar provider registered for model: ${modelKey}`);
52
+ }
53
+ return factory(modelKey);
54
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./IAvatarVideoProvider";
2
+ export * from "./avatarProviderFactory";
3
+ export * from "./providers/klingAvatarProvider";
4
+ export * from "./providers/heygenAvatarProvider";
5
+ export * from "./providers/tavusAvatarProvider";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/avatarGen/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./IAvatarVideoProvider"), exports);
18
+ __exportStar(require("./avatarProviderFactory"), exports);
19
+ __exportStar(require("./providers/klingAvatarProvider"), exports);
20
+ __exportStar(require("./providers/heygenAvatarProvider"), exports);
21
+ __exportStar(require("./providers/tavusAvatarProvider"), exports);
@@ -0,0 +1,45 @@
1
+ import { EVideoGenModels } from "../../../globals/aiModels";
2
+ import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, EAvatarEngine, IAvatarVideoProvider, ISupportsHostedCatalog, VoiceOption } from "../IAvatarVideoProvider";
3
+ /**
4
+ * HeyGen avatar engine — a HOSTED engine (the caller picks a HeyGen-hosted
5
+ * avatar + voice and supplies a script; HeyGen does its own TTS + lipsync).
6
+ *
7
+ * Contract (HeyGen API, verified 2026-06-26 against developers.heygen.com +
8
+ * the published OpenAPI spec; v2 endpoints supported through 2026-10-31):
9
+ * • submit : POST /v2/video/generate → { data: { video_id } }
10
+ * • status : GET /v1/video_status.get?video_id=… → { data: { status, video_url } }
11
+ * • avatars: GET /v2/avatars → { data: { avatars: [...] } }
12
+ * • voices : GET /v2/voices → { data: { voices: [...] } }
13
+ * • auth : X-Api-Key header
14
+ *
15
+ * This is a STANDALONE class (not an adapter over an existing service) because
16
+ * HeyGen has no representation in the generic video factory — avatar gen is its
17
+ * own concern (see IAvatarVideoProvider). Transport (auth + timeout + retry) is
18
+ * owned here, mirroring the per-provider pattern KlingService uses.
19
+ *
20
+ * Capabilities: inputMode "hosted", nativeTts true (HeyGen synthesizes), no
21
+ * multi-scene split (one render per script). It also exposes the hosted catalog
22
+ * (ISupportsHostedCatalog) so the UI / agent can list pickable avatars + voices.
23
+ */
24
+ export declare class HeyGenAvatarProvider implements IAvatarVideoProvider, ISupportsHostedCatalog {
25
+ private readonly modelKey;
26
+ /** Static so callers can branch on capability without constructing (which
27
+ * would require HEYGEN_API_KEY just to read the input mode). */
28
+ static readonly CAPABILITIES: AvatarCapabilities;
29
+ readonly engine = EAvatarEngine.HEYGEN;
30
+ readonly capabilities: AvatarCapabilities;
31
+ private readonly baseUrl;
32
+ private readonly apiKey;
33
+ private readonly submitTimeout;
34
+ private readonly statusTimeout;
35
+ constructor(modelKey?: EVideoGenModels);
36
+ generate(req: AvatarGenerateRequest): Promise<AvatarSubmitResult>;
37
+ checkStatus(query: AvatarStatusQuery): Promise<AvatarStatusResult>;
38
+ listAvatars(): Promise<AvatarOption[]>;
39
+ listVoices(): Promise<VoiceOption[]>;
40
+ private normalizeGender;
41
+ private request;
42
+ /** Retries transient network/timeout/429 failures with a small backoff. */
43
+ private requestWithRetry;
44
+ }
45
+ //# sourceMappingURL=heygenAvatarProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heygenAvatarProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/avatarGen/providers/heygenAvatarProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAI5D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,oBACX,YAAW,oBAAoB,EAAE,sBAAsB;IAmBrD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAjB3B;qEACiE;IACjE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAI9C;IAEF,QAAQ,CAAC,MAAM,wBAAwB;IACvC,QAAQ,CAAC,YAAY,qBAAqC;IAE1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAGrB,QAAQ,GAAE,eAA+C;IAQtE,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6CjE,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgClE,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAYtC,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAwB1C,OAAO,CAAC,eAAe;YAOT,OAAO;IA0BrB,2EAA2E;YAC7D,gBAAgB;CAmD/B"}
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HeyGenAvatarProvider = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const aiModels_1 = require("../../../globals/aiModels");
9
+ const types_1 = require("../../../globals/types");
10
+ const logger_1 = require("../../../utils/logger");
11
+ const types_2 = require("../../aiGen/types");
12
+ const IAvatarVideoProvider_1 = require("../IAvatarVideoProvider");
13
+ /**
14
+ * HeyGen avatar engine — a HOSTED engine (the caller picks a HeyGen-hosted
15
+ * avatar + voice and supplies a script; HeyGen does its own TTS + lipsync).
16
+ *
17
+ * Contract (HeyGen API, verified 2026-06-26 against developers.heygen.com +
18
+ * the published OpenAPI spec; v2 endpoints supported through 2026-10-31):
19
+ * • submit : POST /v2/video/generate → { data: { video_id } }
20
+ * • status : GET /v1/video_status.get?video_id=… → { data: { status, video_url } }
21
+ * • avatars: GET /v2/avatars → { data: { avatars: [...] } }
22
+ * • voices : GET /v2/voices → { data: { voices: [...] } }
23
+ * • auth : X-Api-Key header
24
+ *
25
+ * This is a STANDALONE class (not an adapter over an existing service) because
26
+ * HeyGen has no representation in the generic video factory — avatar gen is its
27
+ * own concern (see IAvatarVideoProvider). Transport (auth + timeout + retry) is
28
+ * owned here, mirroring the per-provider pattern KlingService uses.
29
+ *
30
+ * Capabilities: inputMode "hosted", nativeTts true (HeyGen synthesizes), no
31
+ * multi-scene split (one render per script). It also exposes the hosted catalog
32
+ * (ISupportsHostedCatalog) so the UI / agent can list pickable avatars + voices.
33
+ */
34
+ class HeyGenAvatarProvider {
35
+ constructor(modelKey = aiModels_1.EVideoGenModels.HEYGEN_AVATAR) {
36
+ this.modelKey = modelKey;
37
+ this.engine = IAvatarVideoProvider_1.EAvatarEngine.HEYGEN;
38
+ this.capabilities = HeyGenAvatarProvider.CAPABILITIES;
39
+ this.baseUrl = "https://api.heygen.com";
40
+ this.submitTimeout = 120000; // 2 min — submit can be slow under load
41
+ this.statusTimeout = 60000; // 1 min — status should be fast
42
+ if (!process.env.HEYGEN_API_KEY) {
43
+ throw new Error("Missing HEYGEN_API_KEY in environment variables");
44
+ }
45
+ this.apiKey = process.env.HEYGEN_API_KEY;
46
+ }
47
+ async generate(req) {
48
+ if (req.mode !== "hosted") {
49
+ throw new Error(`HeyGenAvatarProvider only supports hosted requests (got "${req.mode}")`);
50
+ }
51
+ // HeyGen renders a 16:9 720p by default; render mode bumps to 1080p on pro.
52
+ const dimension = req.renderMode === types_2.EVideoMode.PROFESSIONAL
53
+ ? { width: 1920, height: 1080 }
54
+ : { width: 1280, height: 720 };
55
+ const body = {
56
+ video_inputs: [
57
+ {
58
+ character: {
59
+ type: "avatar",
60
+ avatar_id: req.hostedAvatarId,
61
+ avatar_style: "normal",
62
+ },
63
+ voice: {
64
+ type: "text",
65
+ input_text: req.script,
66
+ voice_id: req.hostedVoiceId,
67
+ },
68
+ },
69
+ ],
70
+ dimension,
71
+ };
72
+ const data = await this.request("/v2/video/generate", "POST", body, this.submitTimeout);
73
+ const videoId = data?.data?.video_id;
74
+ if (!videoId) {
75
+ throw new Error(`HeyGen submit returned no video_id: ${JSON.stringify(data?.error ?? data)}`);
76
+ }
77
+ return { providerTaskId: videoId };
78
+ }
79
+ async checkStatus(query) {
80
+ const data = await this.requestWithRetry(`/v1/video_status.get?video_id=${encodeURIComponent(query.providerTaskId)}`, "GET", undefined, this.statusTimeout);
81
+ const providerStatus = data?.data?.status;
82
+ // HeyGen status enum: pending | waiting | processing | completed | failed.
83
+ if (providerStatus === "completed") {
84
+ return {
85
+ status: types_1.EVideoSceneStatus.COMPLETED,
86
+ videoUrl: data?.data?.video_url,
87
+ };
88
+ }
89
+ if (providerStatus === "failed") {
90
+ return {
91
+ status: types_1.EVideoSceneStatus.FAILED,
92
+ errorMessage: data?.data?.error?.message ?? data?.message ?? "HeyGen render failed",
93
+ };
94
+ }
95
+ return { status: types_1.EVideoSceneStatus.PENDING };
96
+ }
97
+ // ─── ISupportsHostedCatalog ───────────────────────────────────────────────
98
+ async listAvatars() {
99
+ const data = await this.requestWithRetry("/v2/avatars", "GET", undefined, this.statusTimeout);
100
+ return (data?.data?.avatars ?? []).map((a) => ({
101
+ id: a.avatar_id,
102
+ name: a.avatar_name ?? a.avatar_id,
103
+ previewUrl: a.preview_image_url,
104
+ }));
105
+ }
106
+ async listVoices() {
107
+ const data = await this.requestWithRetry("/v2/voices", "GET", undefined, this.statusTimeout);
108
+ return (data?.data?.voices ?? []).map((v) => ({
109
+ id: v.voice_id,
110
+ name: v.name ?? v.voice_id,
111
+ gender: this.normalizeGender(v.gender),
112
+ accent: v.language,
113
+ previewUrl: v.preview_audio,
114
+ }));
115
+ }
116
+ // ─── Transport ────────────────────────────────────────────────────────────
117
+ normalizeGender(g) {
118
+ const lower = (g ?? "").toLowerCase();
119
+ if (lower === "male")
120
+ return "male";
121
+ if (lower === "female")
122
+ return "female";
123
+ return "neutral";
124
+ }
125
+ async request(endpoint, method, body, timeout = this.submitTimeout) {
126
+ const config = {
127
+ method,
128
+ url: `${this.baseUrl}${endpoint}`,
129
+ headers: {
130
+ "X-Api-Key": this.apiKey,
131
+ "Content-Type": "application/json",
132
+ },
133
+ timeout,
134
+ data: body,
135
+ };
136
+ const response = await axios_1.default.request(config);
137
+ if (response.status < 200 || response.status >= 300) {
138
+ throw new Error(`HeyGen API Error: ${response.status} ${response.statusText} — ${JSON.stringify(response.data)}`);
139
+ }
140
+ return response.data;
141
+ }
142
+ /** Retries transient network/timeout/429 failures with a small backoff. */
143
+ async requestWithRetry(endpoint, method, body, timeout = this.statusTimeout, maxAttempts = 4) {
144
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
145
+ try {
146
+ return await this.request(endpoint, method, body, timeout);
147
+ }
148
+ catch (err) {
149
+ const e = err;
150
+ const httpStatus = e.response?.status;
151
+ const isTimeout = e.code === "ECONNABORTED" || (e.message?.includes("timeout") ?? false);
152
+ const isNetworkError = e.code === "ECONNRESET" ||
153
+ e.code === "ECONNREFUSED" ||
154
+ e.code === "ENOTFOUND" ||
155
+ e.code === "ERR_NETWORK";
156
+ const isRateLimit = httpStatus === 429;
157
+ const isRetryable = isTimeout || isNetworkError || isRateLimit;
158
+ if (!isRetryable || attempt === maxAttempts) {
159
+ logger_1.logger.error("HeyGen request failed (non-retryable or max attempts)", {
160
+ endpoint,
161
+ attempt,
162
+ maxAttempts,
163
+ httpStatus,
164
+ errorCode: e.code,
165
+ errorMessage: e.message,
166
+ });
167
+ throw err;
168
+ }
169
+ const backoffMs = isRateLimit ? 10000 : 1000;
170
+ logger_1.logger.warn("HeyGen request failed — retrying", {
171
+ endpoint,
172
+ attempt,
173
+ maxAttempts,
174
+ httpStatus,
175
+ backoffMs,
176
+ });
177
+ await new Promise((r) => setTimeout(r, backoffMs));
178
+ }
179
+ }
180
+ throw new Error("Unreachable");
181
+ }
182
+ }
183
+ exports.HeyGenAvatarProvider = HeyGenAvatarProvider;
184
+ /** Static so callers can branch on capability without constructing (which
185
+ * would require HEYGEN_API_KEY just to read the input mode). */
186
+ HeyGenAvatarProvider.CAPABILITIES = {
187
+ inputMode: "hosted",
188
+ nativeTts: true,
189
+ multiSceneSplit: false,
190
+ };
@@ -0,0 +1,32 @@
1
+ import { EVideoGenModels } from "../../../globals/aiModels";
2
+ import { AvatarCapabilities, AvatarGenerateRequest, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, EAvatarEngine, IAvatarVideoProvider } from "../IAvatarVideoProvider";
3
+ /**
4
+ * Kling avatar engine, behind the IAvatarVideoProvider seam.
5
+ *
6
+ * This is intentionally a THIN ADAPTER over the existing `KlingService`, NOT a
7
+ * reimplementation: Kling's avatar endpoint shares the same JWT auth, IPv4-pinned
8
+ * agents, timeout/retry and status-stash transport as regular Kling video, so the
9
+ * avatar submit/poll logic stays exactly where it already lives and is proven
10
+ * (kling.service.ts `generateAvatarVideo` + klingStatus.ts `checkAvatarVideoStatus`).
11
+ * Migrating callers onto this class changes the seam, not Kling's behavior — that
12
+ * byte-for-byte preservation is the Phase 0a regression gate.
13
+ *
14
+ * Kling is "byo-media": caller supplies a face image; WE supply the audio (TTS is
15
+ * run by the orchestrator), so `nativeTts` is false. Long audio is split into
16
+ * scenes and stitched, so `multiSceneSplit` is true. It exposes no hosted catalog,
17
+ * replica training or dubbing — those optional capability interfaces are simply
18
+ * not implemented (ISP).
19
+ */
20
+ export declare class KlingAvatarProvider implements IAvatarVideoProvider {
21
+ private readonly modelKey;
22
+ /** Static so callers can branch on capability without constructing (which
23
+ * would require Kling API keys just to read the input mode). */
24
+ static readonly CAPABILITIES: AvatarCapabilities;
25
+ readonly engine = EAvatarEngine.KLING;
26
+ readonly capabilities: AvatarCapabilities;
27
+ private readonly kling;
28
+ constructor(modelKey?: EVideoGenModels);
29
+ generate(req: AvatarGenerateRequest): Promise<AvatarSubmitResult>;
30
+ checkStatus(query: AvatarStatusQuery): Promise<AvatarStatusResult>;
31
+ }
32
+ //# sourceMappingURL=klingAvatarProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"klingAvatarProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/avatarGen/providers/klingAvatarProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAIjC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAe5D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAd3B;qEACiE;IACjE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAI9C;IAEF,QAAQ,CAAC,MAAM,uBAAuB;IACtC,QAAQ,CAAC,YAAY,qBAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAGlB,QAAQ,GAAE,eAA8C;IAKrE,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAqBjE,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAczE"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KlingAvatarProvider = void 0;
4
+ const aiModels_1 = require("../../../globals/aiModels");
5
+ const kling_service_1 = require("../../aiGen/providers/kling/kling.service");
6
+ const IAvatarVideoProvider_1 = require("../IAvatarVideoProvider");
7
+ const DEFAULT_OUTPUT_PATH = "avatar-videos";
8
+ /**
9
+ * Kling avatar engine, behind the IAvatarVideoProvider seam.
10
+ *
11
+ * This is intentionally a THIN ADAPTER over the existing `KlingService`, NOT a
12
+ * reimplementation: Kling's avatar endpoint shares the same JWT auth, IPv4-pinned
13
+ * agents, timeout/retry and status-stash transport as regular Kling video, so the
14
+ * avatar submit/poll logic stays exactly where it already lives and is proven
15
+ * (kling.service.ts `generateAvatarVideo` + klingStatus.ts `checkAvatarVideoStatus`).
16
+ * Migrating callers onto this class changes the seam, not Kling's behavior — that
17
+ * byte-for-byte preservation is the Phase 0a regression gate.
18
+ *
19
+ * Kling is "byo-media": caller supplies a face image; WE supply the audio (TTS is
20
+ * run by the orchestrator), so `nativeTts` is false. Long audio is split into
21
+ * scenes and stitched, so `multiSceneSplit` is true. It exposes no hosted catalog,
22
+ * replica training or dubbing — those optional capability interfaces are simply
23
+ * not implemented (ISP).
24
+ */
25
+ class KlingAvatarProvider {
26
+ constructor(modelKey = aiModels_1.EVideoGenModels.KLING_AVATAR) {
27
+ this.modelKey = modelKey;
28
+ this.engine = IAvatarVideoProvider_1.EAvatarEngine.KLING;
29
+ this.capabilities = KlingAvatarProvider.CAPABILITIES;
30
+ this.kling = new kling_service_1.KlingService();
31
+ }
32
+ async generate(req) {
33
+ if (req.mode !== "byo-media") {
34
+ throw new Error(`KlingAvatarProvider only supports byo-media requests (got "${req.mode}")`);
35
+ }
36
+ // Delegates to the existing Kling avatar path (routes on modelKey ===
37
+ // "kling-avatar" inside generateVideo, before any type-based dispatch — so
38
+ // `type` is intentionally omitted, matching the prior call site).
39
+ const result = await this.kling.generateVideo({
40
+ modelKey: this.modelKey,
41
+ inputImageUrl: req.faceImageUrl,
42
+ inputAudioUrl: req.audioUrl,
43
+ prompt: req.prompt,
44
+ mode: req.renderMode,
45
+ });
46
+ return { providerTaskId: result.task };
47
+ }
48
+ async checkStatus(query) {
49
+ const result = await this.kling.checkVideoStatus({
50
+ task: query.providerTaskId,
51
+ outputFilename: query.outputFilename,
52
+ outputFilePath: query.outputFilePath ?? DEFAULT_OUTPUT_PATH,
53
+ modelKey: this.modelKey,
54
+ });
55
+ return {
56
+ status: result.status,
57
+ videoUrl: result.videoUrl,
58
+ errorMessage: result.errorMessage,
59
+ };
60
+ }
61
+ }
62
+ exports.KlingAvatarProvider = KlingAvatarProvider;
63
+ /** Static so callers can branch on capability without constructing (which
64
+ * would require Kling API keys just to read the input mode). */
65
+ KlingAvatarProvider.CAPABILITIES = {
66
+ inputMode: "byo-media",
67
+ nativeTts: false,
68
+ multiSceneSplit: true,
69
+ };