vidspotai-shared 1.0.95 → 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.
- package/lib/globals/aiModels/enums.d.ts +2 -0
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +5 -0
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/hostedAvatars.d.ts +22 -0
- package/lib/globals/aiModels/providers/hostedAvatars.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/hostedAvatars.js +129 -0
- package/lib/globals/types.d.ts +58 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +61 -1
- package/lib/models/demoVideoProject.model.d.ts +244 -0
- package/lib/models/demoVideoProject.model.d.ts.map +1 -0
- package/lib/models/demoVideoProject.model.js +2 -0
- package/lib/models/githubConnection.model.d.ts +35 -0
- package/lib/models/githubConnection.model.d.ts.map +1 -0
- package/lib/models/githubConnection.model.js +2 -0
- package/lib/models/index.d.ts +3 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +3 -0
- package/lib/models/outreach.model.d.ts +175 -0
- package/lib/models/outreach.model.d.ts.map +1 -0
- package/lib/models/outreach.model.js +2 -0
- package/lib/models/video.model.d.ts +4 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/brandKit.schema.d.ts +4 -0
- package/lib/schemas/brandKit.schema.d.ts.map +1 -1
- package/lib/schemas/brandKit.schema.js +10 -0
- package/lib/schemas/demoQuestion.schema.d.ts +286 -0
- package/lib/schemas/demoQuestion.schema.d.ts.map +1 -0
- package/lib/schemas/demoQuestion.schema.js +210 -0
- package/lib/schemas/demoSpec.schema.d.ts +109 -6
- package/lib/schemas/demoSpec.schema.d.ts.map +1 -1
- package/lib/schemas/demoSpec.schema.js +95 -7
- package/lib/schemas/index.d.ts +1 -0
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +1 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +9 -1
- package/lib/services/agent/taskPoller.d.ts.map +1 -1
- package/lib/services/agent/taskPoller.js +17 -6
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +21 -9
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateAvatarVideo.tool.js +135 -39
- package/lib/services/aiGen/aiGenFactory.service.d.ts +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +10 -2
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts +136 -0
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/IAvatarVideoProvider.js +42 -0
- package/lib/services/avatarGen/avatarProviderFactory.d.ts +18 -0
- package/lib/services/avatarGen/avatarProviderFactory.d.ts.map +1 -0
- package/lib/services/avatarGen/avatarProviderFactory.js +54 -0
- package/lib/services/avatarGen/index.d.ts +6 -0
- package/lib/services/avatarGen/index.d.ts.map +1 -0
- package/lib/services/avatarGen/index.js +21 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts +45 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.js +190 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts +32 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.js +69 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts +56 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.js +183 -0
- package/lib/services/demo/demoAuthor.d.ts +45 -0
- package/lib/services/demo/demoAuthor.d.ts.map +1 -0
- package/lib/services/demo/demoAuthor.js +75 -0
- package/lib/services/demo/demoAuthorNormalize.d.ts +49 -0
- package/lib/services/demo/demoAuthorNormalize.d.ts.map +1 -0
- package/lib/services/demo/demoAuthorNormalize.js +327 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts +102 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts.map +1 -0
- package/lib/services/demo/demoAuthorPrompt.js +243 -0
- package/lib/services/demo/demoCredits.d.ts +20 -0
- package/lib/services/demo/demoCredits.d.ts.map +1 -0
- package/lib/services/demo/demoCredits.js +51 -0
- package/lib/services/demo/demoMediaGuard.d.ts +43 -0
- package/lib/services/demo/demoMediaGuard.d.ts.map +1 -0
- package/lib/services/demo/demoMediaGuard.js +207 -0
- package/lib/services/demo/demoMusic.d.ts +13 -0
- package/lib/services/demo/demoMusic.d.ts.map +1 -0
- package/lib/services/demo/demoMusic.js +93 -0
- package/lib/services/demo/demoPrefill.d.ts +76 -0
- package/lib/services/demo/demoPrefill.d.ts.map +1 -0
- package/lib/services/demo/demoPrefill.js +435 -0
- package/lib/services/demo/demoRevisePrompt.d.ts +17 -0
- package/lib/services/demo/demoRevisePrompt.d.ts.map +1 -0
- package/lib/services/demo/demoRevisePrompt.js +85 -0
- package/lib/services/demo/demoReviser.d.ts +63 -0
- package/lib/services/demo/demoReviser.d.ts.map +1 -0
- package/lib/services/demo/demoReviser.js +81 -0
- package/lib/services/demo/demoScriptPrompt.d.ts +63 -0
- package/lib/services/demo/demoScriptPrompt.d.ts.map +1 -0
- package/lib/services/demo/demoScriptPrompt.js +234 -0
- package/lib/services/demo/demoScriptWriter.d.ts +65 -0
- package/lib/services/demo/demoScriptWriter.d.ts.map +1 -0
- package/lib/services/demo/demoScriptWriter.js +211 -0
- package/lib/services/demo/demoTriage.d.ts +65 -0
- package/lib/services/demo/demoTriage.d.ts.map +1 -0
- package/lib/services/demo/demoTriage.js +130 -0
- package/lib/services/demo/githubOAuth.d.ts +78 -0
- package/lib/services/demo/githubOAuth.d.ts.map +1 -0
- package/lib/services/demo/githubOAuth.js +209 -0
- package/lib/services/demo/githubOAuthState.d.ts +10 -0
- package/lib/services/demo/githubOAuthState.d.ts.map +1 -0
- package/lib/services/demo/githubOAuthState.js +63 -0
- package/lib/services/demo/index.d.ts +24 -0
- package/lib/services/demo/index.d.ts.map +1 -0
- package/lib/services/demo/index.js +39 -0
- package/lib/services/firestore.service.d.ts +11 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +24 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +2 -0
- package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
- package/lib/services/tts/providers/elevenlabs.service.js +16 -8
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/outreachTemplate.d.ts +46 -0
- package/lib/utils/outreachTemplate.d.ts.map +1 -0
- package/lib/utils/outreachTemplate.js +174 -0
- package/package.json +1 -1
|
@@ -4,79 +4,177 @@ exports.generateAvatarVideoTool = void 0;
|
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const aiModels_1 = require("../../../globals/aiModels");
|
|
6
6
|
const firebase_1 = require("../../../libs/firebase");
|
|
7
|
-
const
|
|
7
|
+
const avatarProviderFactory_1 = require("../../avatarGen/avatarProviderFactory");
|
|
8
8
|
const types_1 = require("../../aiGen/types");
|
|
9
9
|
const rateLimiter_1 = require("../../rateLimiter");
|
|
10
10
|
const ttsFactory_service_1 = require("../../tts/ttsFactory.service");
|
|
11
11
|
const toolRegistry_1 = require("../toolRegistry");
|
|
12
12
|
/**
|
|
13
|
-
* generate_avatar_video —
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* before handing off, since Kling avatar requires a public sound_file URL).
|
|
13
|
+
* generate_avatar_video — drives avatar generation through the dedicated avatar
|
|
14
|
+
* provider seam (getAvatarVideoProvider / IAvatarVideoProvider), so the planner's
|
|
15
|
+
* `talking-head-avatar` scene strategy is executable. Avatar gen is handled by
|
|
16
|
+
* the avatar provider — NOT the generic video-gen provider. Two engine families:
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* - byo-media (default kling-avatar): caller supplies a presenter face image
|
|
19
|
+
* plus either a pre-uploaded audio URL or raw TTS text (the tool synthesizes
|
|
20
|
+
* via ElevenLabs + uploads to GCS first, since the engine needs a public
|
|
21
|
+
* audio URL).
|
|
22
|
+
* - hosted (heygen-avatar / tavus-avatar, via `model`): caller supplies a
|
|
23
|
+
* provider-hosted avatar id + a script; the engine runs its own TTS/lipsync,
|
|
24
|
+
* so the tool does NO TTS and passes no audio.
|
|
25
|
+
*
|
|
26
|
+
* Returns a provider task id; the executor's TaskPoller polls completion — it
|
|
27
|
+
* routes hosted models through the avatar seam and everything else through the
|
|
28
|
+
* generic video factory, so this works for both families.
|
|
21
29
|
*/
|
|
22
30
|
const InputSchema = zod_1.z
|
|
23
31
|
.object({
|
|
32
|
+
model: zod_1.z
|
|
33
|
+
.nativeEnum(aiModels_1.EVideoGenModels)
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Avatar engine. Default kling-avatar (byo-media: animate a face image). heygen-avatar / tavus-avatar are hosted (animate a provider-hosted avatar + native TTS)."),
|
|
24
36
|
inputImageUrl: zod_1.z
|
|
25
37
|
.string()
|
|
26
38
|
.url()
|
|
27
|
-
.
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("byo-media: presenter face still the engine animates to lipsync the audio. Required for byo-media; omit for hosted."),
|
|
41
|
+
hostedAvatarId: zod_1.z
|
|
42
|
+
.string()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe("hosted: provider-hosted avatar id (HeyGen) or replica_id (Tavus) to animate. Required for hosted engines."),
|
|
45
|
+
hostedVoiceId: zod_1.z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("hosted: provider-hosted voice id (HeyGen). Unused for Tavus (the replica owns its voice)."),
|
|
28
49
|
ttsText: zod_1.z
|
|
29
50
|
.string()
|
|
30
51
|
.min(1)
|
|
31
52
|
.optional()
|
|
32
|
-
.describe("VO line
|
|
53
|
+
.describe("VO line / script. byo-media: synthesized to audio (or use inputAudioUrl; if both set, inputAudioUrl wins). hosted: spoken natively by the engine (required)."),
|
|
33
54
|
inputAudioUrl: zod_1.z
|
|
34
55
|
.string()
|
|
35
56
|
.url()
|
|
36
57
|
.optional()
|
|
37
|
-
.describe("
|
|
58
|
+
.describe("byo-media only: pre-uploaded audio URL (mp3/wav). Skips internal TTS+upload."),
|
|
38
59
|
voiceId: zod_1.z.string().optional(),
|
|
39
60
|
languageCode: zod_1.z.string().optional(),
|
|
40
61
|
mode: zod_1.z.enum(["std", "pro"]).default("std"),
|
|
41
62
|
prompt: zod_1.z
|
|
42
63
|
.string()
|
|
43
64
|
.optional()
|
|
44
|
-
.describe("
|
|
65
|
+
.describe("byo-media only: optional motion/emotion hint passed through to the engine."),
|
|
45
66
|
})
|
|
46
67
|
.superRefine((v, ctx) => {
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
if (v.model && (0, avatarProviderFactory_1.isHostedAvatarModel)(v.model)) {
|
|
69
|
+
if (!v.hostedAvatarId) {
|
|
70
|
+
ctx.addIssue({
|
|
71
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
72
|
+
message: "hostedAvatarId is required for hosted avatar engines.",
|
|
73
|
+
path: ["hostedAvatarId"],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (!v.ttsText) {
|
|
77
|
+
ctx.addIssue({
|
|
78
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
79
|
+
message: "ttsText (the script) is required for hosted avatar engines.",
|
|
80
|
+
path: ["ttsText"],
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
if (!v.inputImageUrl) {
|
|
86
|
+
ctx.addIssue({
|
|
87
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
88
|
+
message: "inputImageUrl is required for byo-media avatar engines.",
|
|
89
|
+
path: ["inputImageUrl"],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (!v.ttsText && !v.inputAudioUrl) {
|
|
93
|
+
ctx.addIssue({
|
|
94
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
95
|
+
message: "Either ttsText or inputAudioUrl is required.",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
52
98
|
}
|
|
53
99
|
});
|
|
54
100
|
const OutputSchema = zod_1.z.object({
|
|
55
101
|
status: zod_1.z.literal("triggered"),
|
|
56
102
|
taskId: zod_1.z.string(),
|
|
57
|
-
audioUrl: zod_1.z
|
|
103
|
+
audioUrl: zod_1.z
|
|
104
|
+
.string()
|
|
105
|
+
.url()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe("byo-media: audio URL fed to the engine — host can reuse for caption sync. Absent for hosted engines (native TTS)."),
|
|
58
108
|
});
|
|
59
109
|
exports.generateAvatarVideoTool = {
|
|
60
110
|
name: "generate_avatar_video",
|
|
61
111
|
description: [
|
|
62
|
-
"Generate a talking-head avatar video
|
|
63
|
-
"
|
|
112
|
+
"Generate a talking-head avatar video that lipsyncs a voiceover. Routed",
|
|
113
|
+
"through the dedicated avatar provider seam. Two engine families: byo-media",
|
|
114
|
+
"(default kling-avatar) animates a presenter face still you supply; hosted",
|
|
115
|
+
"(heygen-avatar / tavus-avatar, via `model`) animates a provider-hosted",
|
|
116
|
+
"avatar and runs its own TTS from a script.",
|
|
64
117
|
"Use this for the `talking-head-avatar` scene strategy. Do NOT use it for",
|
|
65
118
|
"general motion shots — generate_video is cheaper and more flexible there.",
|
|
66
119
|
"Examples:",
|
|
67
120
|
' { inputImageUrl: "https://.../face.png", ttsText: "Hi, today we\'re testing the new serum." }',
|
|
68
121
|
' { inputImageUrl: "https://.../face.png", inputAudioUrl: "https://.../vo.mp3", mode: "pro" }',
|
|
122
|
+
' { model: "heygen-avatar", hostedAvatarId: "Daisy-inskirt-20220818", hostedVoiceId: "2d5b0e6cf36f460aa7fc47e3eee4ba54", ttsText: "Welcome back!" }',
|
|
69
123
|
].join(" "),
|
|
70
124
|
inputSchema: InputSchema,
|
|
71
125
|
outputSchema: OutputSchema,
|
|
72
126
|
idempotent: false,
|
|
73
127
|
estimateCost: async (input) => {
|
|
74
|
-
//
|
|
128
|
+
// Without a length we assume 6s (typical scene).
|
|
75
129
|
const approxSec = input.ttsText ? Math.max(2, Math.ceil(input.ttsText.length / 15)) : 6;
|
|
130
|
+
const modelKey = input.model ?? aiModels_1.EVideoGenModels.KLING_AVATAR;
|
|
131
|
+
if ((0, avatarProviderFactory_1.isHostedAvatarModel)(modelKey)) {
|
|
132
|
+
// Hosted engines bill per generated MINUTE (min 1 minute).
|
|
133
|
+
const perMinute = aiModels_1.aiModelConfigs[modelKey]?.cost?.perMinute ?? 0.5;
|
|
134
|
+
const billedMinutes = Math.max(1, Math.ceil(approxSec / 60));
|
|
135
|
+
return Math.ceil(perMinute * billedMinutes * 100); // rough credit conversion
|
|
136
|
+
}
|
|
137
|
+
// byo-media (Kling) bills per audio second.
|
|
76
138
|
const perSec = input.mode === "pro" ? 0.028 : 0.014;
|
|
77
|
-
return Math.ceil(approxSec * perSec * 100);
|
|
139
|
+
return Math.ceil(approxSec * perSec * 100);
|
|
78
140
|
},
|
|
79
141
|
handler: async (input, ctx) => {
|
|
142
|
+
const modelKey = input.model ?? aiModels_1.EVideoGenModels.KLING_AVATAR;
|
|
143
|
+
const renderMode = input.mode === "pro" ? types_1.EVideoMode.PROFESSIONAL : types_1.EVideoMode.STANDARD;
|
|
144
|
+
// ── Hosted engines (HeyGen/Tavus) ────────────────────────────────────────
|
|
145
|
+
// The engine does its own TTS + lipsync from the script, so there's no TTS
|
|
146
|
+
// synthesis / GCS upload here. Submit and hand the task id to the poller,
|
|
147
|
+
// which routes hosted models through the avatar seam.
|
|
148
|
+
if ((0, avatarProviderFactory_1.isHostedAvatarModel)(modelKey)) {
|
|
149
|
+
const limiter = (0, rateLimiter_1.getAiGenModelRateLimiter)(modelKey);
|
|
150
|
+
await limiter.waitUntilAvailable();
|
|
151
|
+
let heldSlot = true;
|
|
152
|
+
try {
|
|
153
|
+
const provider = (0, avatarProviderFactory_1.getAvatarVideoProvider)(modelKey);
|
|
154
|
+
const result = await provider.generate({
|
|
155
|
+
mode: "hosted",
|
|
156
|
+
hostedAvatarId: input.hostedAvatarId,
|
|
157
|
+
hostedVoiceId: input.hostedVoiceId ?? "",
|
|
158
|
+
script: input.ttsText,
|
|
159
|
+
locale: input.languageCode,
|
|
160
|
+
renderMode,
|
|
161
|
+
});
|
|
162
|
+
const taskId = result.providerTaskId?.taskId ??
|
|
163
|
+
result.providerTaskId?.id ??
|
|
164
|
+
(typeof result.providerTaskId === "string" ? result.providerTaskId : "unknown");
|
|
165
|
+
if (taskId === "unknown") {
|
|
166
|
+
limiter.releaseSlot();
|
|
167
|
+
heldSlot = false;
|
|
168
|
+
}
|
|
169
|
+
return { status: "triggered", taskId };
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
if (heldSlot)
|
|
173
|
+
limiter.releaseSlot();
|
|
174
|
+
throw err;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// ── byo-media engines (Kling) ─────────────────────────────────────────────
|
|
80
178
|
let audioUrl = input.inputAudioUrl;
|
|
81
179
|
if (!audioUrl) {
|
|
82
180
|
const ttsLimiter = (0, rateLimiter_1.getTtsProviderRateLimiter)("elevenlabs");
|
|
@@ -100,29 +198,27 @@ exports.generateAvatarVideoTool = {
|
|
|
100
198
|
const [signedUrl] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
|
|
101
199
|
audioUrl = signedUrl;
|
|
102
200
|
}
|
|
103
|
-
// Hold the
|
|
201
|
+
// Hold the byo-media model slot through return — host's TaskPoller releases
|
|
104
202
|
// when the task settles. Release here on submit error.
|
|
105
|
-
const limiter = (0, rateLimiter_1.getAiGenModelRateLimiter)(
|
|
203
|
+
const limiter = (0, rateLimiter_1.getAiGenModelRateLimiter)(modelKey);
|
|
106
204
|
await limiter.waitUntilAvailable();
|
|
107
205
|
let heldSlot = true;
|
|
108
206
|
try {
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
207
|
+
// byo-media avatar request: a face still + the audio we just resolved. The
|
|
208
|
+
// avatar provider owns endpoint/type dispatch internally (Kling routes on
|
|
209
|
+
// modelKey === "kling-avatar"), so no generic-video `type` is passed here.
|
|
210
|
+
// inputImageUrl presence is guaranteed by the byo-media superRefine branch.
|
|
211
|
+
const provider = (0, avatarProviderFactory_1.getAvatarVideoProvider)(modelKey);
|
|
212
|
+
const result = await provider.generate({
|
|
213
|
+
mode: "byo-media",
|
|
214
|
+
faceImageUrl: input.inputImageUrl,
|
|
215
|
+
audioUrl,
|
|
118
216
|
prompt: input.prompt,
|
|
119
|
-
|
|
120
|
-
inputAudioUrl: audioUrl,
|
|
121
|
-
mode: input.mode === "pro" ? types_1.EVideoMode.PROFESSIONAL : types_1.EVideoMode.STANDARD,
|
|
217
|
+
renderMode,
|
|
122
218
|
});
|
|
123
|
-
const taskId = result.
|
|
124
|
-
result.
|
|
125
|
-
(typeof result.
|
|
219
|
+
const taskId = result.providerTaskId?.taskId ??
|
|
220
|
+
result.providerTaskId?.id ??
|
|
221
|
+
(typeof result.providerTaskId === "string" ? result.providerTaskId : "unknown");
|
|
126
222
|
if (taskId === "unknown") {
|
|
127
223
|
limiter.releaseSlot();
|
|
128
224
|
heldSlot = false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseAiGenProviderService } from "./providers/baseAiGenProvider.service";
|
|
2
2
|
import { EImageGenModelKey, EMusicGenModels, ESfxGenModels, ETextGenModels, EVideoGenModels, TAiGenModel } from "../../globals/aiModels";
|
|
3
3
|
type AiGenServiceConstructor = new () => BaseAiGenProviderService;
|
|
4
|
-
export declare const videoServicesMap: Record<EVideoGenModels, AiGenServiceConstructor
|
|
4
|
+
export declare const videoServicesMap: Partial<Record<EVideoGenModels, AiGenServiceConstructor>>;
|
|
5
5
|
/**
|
|
6
6
|
* Image-gen factory. Each provider service implements `generateImage()` (sync;
|
|
7
7
|
* returns a URL or base64 in a single API roundtrip — no BullMQ worker needed).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiGenFactory.service.d.ts","sourceRoot":"","sources":["../../../src/services/aiGen/aiGenFactory.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EACL,iBAAiB,EAEjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAchC,KAAK,uBAAuB,GAAG,UAAU,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"aiGenFactory.service.d.ts","sourceRoot":"","sources":["../../../src/services/aiGen/aiGenFactory.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EACL,iBAAiB,EAEjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAchC,KAAK,uBAAuB,GAAG,UAAU,wBAAwB,CAAC;AASlE,eAAO,MAAM,gBAAgB,EAAE,OAAO,CACpC,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC,CA+DjD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,iBAAiB,EACjB,uBAAuB,CA2CxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,eAAe,EACf,uBAAuB,CAMxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,aAAa,EACb,uBAAuB,CAGxB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,uBAAuB,CAsBzE,CAAC;AAEJ,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,WAAW,GACpB,wBAAwB,CAmB1B"}
|
|
@@ -14,6 +14,13 @@ const pixverse_service_1 = require("./providers/pixverse/pixverse.service");
|
|
|
14
14
|
const bytedance_service_1 = require("./providers/bytedance/bytedance.service");
|
|
15
15
|
const elevenlabs_service_1 = require("./providers/elevenlabs/elevenlabs.service");
|
|
16
16
|
const anthropic_service_1 = require("./providers/anthropic/anthropic.service");
|
|
17
|
+
// Partial, intentionally: hosted avatar engines (heygen-avatar, tavus-avatar)
|
|
18
|
+
// are NOT generic video models — they're handled by the dedicated avatar seam
|
|
19
|
+
// (getAvatarVideoProvider / IAvatarVideoProvider). getAiGenProviderService gates
|
|
20
|
+
// on `modelKey in videoServicesMap` and throws for anything absent, so these
|
|
21
|
+
// keys correctly resolve through the avatar factory instead. (kling-avatar stays
|
|
22
|
+
// here because KlingService still backs both its generic-credit path and the
|
|
23
|
+
// KlingAvatarProvider adapter.)
|
|
17
24
|
exports.videoServicesMap = {
|
|
18
25
|
// --- Pixverse ---
|
|
19
26
|
"pixverse-v6": pixverse_service_1.PixVerseService,
|
|
@@ -157,8 +164,9 @@ exports.textServicesMap = {
|
|
|
157
164
|
// "openai-gpt-3.5-turbo": OpenaiService,
|
|
158
165
|
};
|
|
159
166
|
function getAiGenProviderService(modelKey) {
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
const VideoService = exports.videoServicesMap[modelKey];
|
|
168
|
+
if (VideoService) {
|
|
169
|
+
return new VideoService();
|
|
162
170
|
}
|
|
163
171
|
if (modelKey in exports.imageServicesMap) {
|
|
164
172
|
return new exports.imageServicesMap[modelKey]();
|
|
@@ -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"}
|