vidspotai-shared 1.0.113 → 1.0.115
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/types.d.ts +17 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +18 -0
- package/lib/libs/index.d.ts +1 -0
- package/lib/libs/index.d.ts.map +1 -1
- package/lib/libs/index.js +1 -0
- package/lib/libs/mediaStore.d.ts +3 -31
- package/lib/libs/mediaStore.d.ts.map +1 -1
- package/lib/libs/mediaStore.js +16 -140
- package/lib/libs/storage/GcsBackend.d.ts +9 -0
- package/lib/libs/storage/GcsBackend.d.ts.map +1 -0
- package/lib/libs/storage/GcsBackend.js +42 -0
- package/lib/libs/storage/MediaStorage.d.ts +117 -0
- package/lib/libs/storage/MediaStorage.d.ts.map +1 -0
- package/lib/libs/storage/MediaStorage.js +117 -0
- package/lib/libs/storage/R2Backend.d.ts +42 -0
- package/lib/libs/storage/R2Backend.d.ts.map +1 -0
- package/lib/libs/storage/R2Backend.js +175 -0
- package/lib/libs/storage/StorageBackend.d.ts +41 -0
- package/lib/libs/storage/StorageBackend.d.ts.map +1 -0
- package/lib/libs/storage/StorageBackend.js +2 -0
- package/lib/libs/storage/cdnUrl.d.ts +27 -0
- package/lib/libs/storage/cdnUrl.d.ts.map +1 -0
- package/lib/libs/storage/cdnUrl.js +48 -0
- package/lib/libs/storage/index.d.ts +6 -0
- package/lib/libs/storage/index.d.ts.map +1 -0
- package/lib/libs/storage/index.js +21 -0
- package/lib/models/agent.model.d.ts +27 -0
- package/lib/models/agent.model.d.ts.map +1 -1
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/models/outreach.model.d.ts +7 -1
- package/lib/models/outreach.model.d.ts.map +1 -1
- package/lib/models/outreachIntegration.model.d.ts +42 -0
- package/lib/models/outreachIntegration.model.d.ts.map +1 -0
- package/lib/models/outreachIntegration.model.js +8 -0
- package/lib/models/video.model.d.ts +7 -1
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.d.ts +1 -0
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +10 -0
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateAvatarVideo.tool.js +3 -5
- package/lib/services/agent/tools/planVideo.tool.d.ts +1 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.js +5 -11
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.js +5 -0
- package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/elevenlabs/elevenlabs.service.js +3 -7
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +7 -4
- package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/googleMusic.js +3 -7
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +16 -7
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +2 -2
- package/lib/services/aiGen/providers/kling/klingImage.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/klingImage.service.js +3 -5
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts +1 -1
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/klingStatus.js +8 -19
- package/lib/services/aiGen/providers/minimax/minimax.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/minimax/minimax.service.js +7 -17
- package/lib/services/aiGen/providers/openai/openai.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/openai/openai.service.js +5 -13
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +5 -0
- package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/runway.service.js +5 -10
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts +25 -3
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts.map +1 -1
- package/lib/services/avatarGen/IAvatarVideoProvider.js +2 -1
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts +23 -2
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts.map +1 -1
- package/lib/services/avatarGen/providers/heygenAvatarProvider.js +71 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts +3 -4
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts.map +1 -1
- package/lib/services/avatarGen/providers/tavusAvatarProvider.js +17 -0
- package/lib/services/editor/planToProject.d.ts.map +1 -1
- package/lib/services/editor/planToProject.js +29 -1
- package/lib/services/firestore.service.d.ts +3 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +7 -0
- package/lib/services/gcp/uploadAudioBuffer.d.ts.map +1 -1
- package/lib/services/gcp/uploadAudioBuffer.js +4 -0
- package/lib/services/index.d.ts +1 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +1 -0
- package/lib/services/outreachWebhooks.service.d.ts +24 -0
- package/lib/services/outreachWebhooks.service.d.ts.map +1 -0
- package/lib/services/outreachWebhooks.service.js +41 -0
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ exports.OpenaiService = void 0;
|
|
|
38
38
|
const openai_1 = __importStar(require("openai"));
|
|
39
39
|
const aiModels_1 = require("../../../../globals/aiModels");
|
|
40
40
|
const types_1 = require("../../../../globals/types");
|
|
41
|
-
const
|
|
41
|
+
const storage_1 = require("../../../../libs/storage");
|
|
42
42
|
const utils_1 = require("../../../../utils");
|
|
43
43
|
const logger_1 = require("../../../../utils/logger");
|
|
44
44
|
const errors_1 = require("../../../../utils/errors");
|
|
@@ -148,15 +148,9 @@ class OpenaiService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
148
148
|
const response = await this.client.videos.downloadContent(task);
|
|
149
149
|
const blob = await response.blob();
|
|
150
150
|
const buffer = Buffer.from(await blob.arrayBuffer());
|
|
151
|
-
// Upload to
|
|
151
|
+
// Upload to storage — GCS write + best-effort R2 mirror (zero-egress).
|
|
152
152
|
const filePath = `${outputFilePath}/${outputFilename}.mp4`;
|
|
153
|
-
const
|
|
154
|
-
await file.save(buffer, { contentType: "video/mp4" });
|
|
155
|
-
// Generate a signed URL
|
|
156
|
-
const [signedUrl] = await file.getSignedUrl({
|
|
157
|
-
action: "read",
|
|
158
|
-
expires: "03-09-2491",
|
|
159
|
-
});
|
|
153
|
+
const signedUrl = await storage_1.mediaStorage.put(filePath, buffer, "video/mp4");
|
|
160
154
|
return {
|
|
161
155
|
status: types_1.EVideoSceneStatus.COMPLETED,
|
|
162
156
|
videoUrl: signedUrl,
|
|
@@ -307,7 +301,6 @@ class OpenaiService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
307
301
|
}
|
|
308
302
|
}
|
|
309
303
|
const data = resp.data ?? [];
|
|
310
|
-
const bucket = (0, firebase_1.getBucket)();
|
|
311
304
|
const ts = Date.now();
|
|
312
305
|
const ext = params.outputFormat ?? "png";
|
|
313
306
|
const urls = [];
|
|
@@ -323,9 +316,8 @@ class OpenaiService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
323
316
|
else
|
|
324
317
|
continue;
|
|
325
318
|
const path = `images/openai/${ts}-${Math.random().toString(36).slice(2, 8)}-${i}.${ext}`;
|
|
326
|
-
|
|
327
|
-
await
|
|
328
|
-
const [signed] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
|
|
319
|
+
// mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
|
|
320
|
+
const signed = await storage_1.mediaStorage.put(path, bytes, `image/${ext}`);
|
|
329
321
|
urls.push(signed);
|
|
330
322
|
}
|
|
331
323
|
if (!urls.length)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixverse.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/pixverse/pixverse.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"pixverse.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/pixverse/pixverse.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAgGlB,qBAAa,eAAgB,SAAQ,wBAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAK1E;;;;;;OAMG;YACW,WAAW;IA6CnB,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAyL3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoHjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAkDjD"}
|
|
@@ -10,6 +10,7 @@ const helpers_1 = require("../../helpers");
|
|
|
10
10
|
const aiModels_1 = require("../../../../globals/aiModels");
|
|
11
11
|
const types_1 = require("../../../../globals/types");
|
|
12
12
|
const firebase_1 = require("../../../../libs/firebase");
|
|
13
|
+
const storage_1 = require("../../../../libs/storage");
|
|
13
14
|
const helpers_2 = require("../../../../utils/helpers");
|
|
14
15
|
const mp4Duration_1 = require("../../../../utils/mp4Duration");
|
|
15
16
|
const logger_1 = require("../../../../utils/logger");
|
|
@@ -372,6 +373,10 @@ class PixVerseService extends baseAiGenProvider_service_1.BaseAiGenProviderServi
|
|
|
372
373
|
},
|
|
373
374
|
},
|
|
374
375
|
});
|
|
376
|
+
// mediaStorage: best-effort R2 mirror (zero-egress delivery). GCS keeps the
|
|
377
|
+
// firebaseStorage download-token URL as the stored system-of-record URL; the
|
|
378
|
+
// CDN Worker resolves either URL family to the same R2 object.
|
|
379
|
+
await storage_1.mediaStorage.mirrorBytes(filePath, buffer, "video/mp4");
|
|
375
380
|
const publicVideoUrl = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}` +
|
|
376
381
|
`/o/${encodeURIComponent(filePath)}?alt=media&token=${downloadToken}`;
|
|
377
382
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/runway/runway.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAIlB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;YAUlB,OAAO;IAgCf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA6G3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"runway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/runway/runway.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAIlB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;YAUlB,OAAO;IAgCf,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA6G3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuDjD,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,SAAiB,EAAE,SAAa,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;IA0BhI;;;;;;;;OAQG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;CAyElC"}
|
|
@@ -7,7 +7,7 @@ exports.RunwayService = void 0;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const aiModels_1 = require("../../../../globals/aiModels");
|
|
9
9
|
const types_1 = require("../../../../globals/types");
|
|
10
|
-
const
|
|
10
|
+
const storage_1 = require("../../../../libs/storage");
|
|
11
11
|
const helpers_1 = require("../../../../utils/helpers");
|
|
12
12
|
const logger_1 = require("../../../../utils/logger");
|
|
13
13
|
const helpers_2 = require("../../helpers");
|
|
@@ -161,12 +161,8 @@ class RunwayService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
161
161
|
}
|
|
162
162
|
const buffer = Buffer.from(videoResp.data);
|
|
163
163
|
const filePath = `${outputFilePath}/${outputFilename}.mp4`;
|
|
164
|
-
|
|
165
|
-
await
|
|
166
|
-
const [signedUrl] = await file.getSignedUrl({
|
|
167
|
-
action: "read",
|
|
168
|
-
expires: "03-09-2491",
|
|
169
|
-
});
|
|
164
|
+
// mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
|
|
165
|
+
const signedUrl = await storage_1.mediaStorage.put(filePath, buffer, "video/mp4");
|
|
170
166
|
return {
|
|
171
167
|
videoUrl: signedUrl,
|
|
172
168
|
status: types_1.EVideoSceneStatus.COMPLETED,
|
|
@@ -264,9 +260,8 @@ class RunwayService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
264
260
|
const ext = (contentType.split("/")[1] ?? "png").toLowerCase();
|
|
265
261
|
const ts = Date.now();
|
|
266
262
|
const path = `images/runway/${ts}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
|
|
267
|
-
|
|
268
|
-
await
|
|
269
|
-
const [signed] = await file.getSignedUrl({ action: "read", expires: "03-09-2491" });
|
|
263
|
+
// mediaStorage: GCS write + best-effort R2 mirror (zero-egress delivery).
|
|
264
|
+
const signed = await storage_1.mediaStorage.put(path, Buffer.from(imgResp.data), contentType);
|
|
270
265
|
return {
|
|
271
266
|
imageUrl: signed,
|
|
272
267
|
providerRequestId: run.id,
|
|
@@ -120,11 +120,33 @@ export interface ISupportsHostedCatalog {
|
|
|
120
120
|
listAvatars(): Promise<AvatarOption[]>;
|
|
121
121
|
listVoices(): Promise<VoiceOption[]>;
|
|
122
122
|
}
|
|
123
|
+
export interface CreateReplicaResult {
|
|
124
|
+
/** Provider-scoped id for the trained replica/look. Persist it, and once
|
|
125
|
+
* status is "ready" pass it straight through as `hostedAvatarId`. */
|
|
126
|
+
replicaId: string;
|
|
127
|
+
/**
|
|
128
|
+
* Present only when the engine requires an out-of-band consent step before
|
|
129
|
+
* the replica can render (HeyGen: a hosted webcam page the subject must
|
|
130
|
+
* open within 24h). Absent when the engine captures consent as part of
|
|
131
|
+
* training itself (Tavus: a consent clip is submitted in the same call).
|
|
132
|
+
*/
|
|
133
|
+
consentUrl?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Opaque per-engine bookkeeping the caller must persist and pass back to
|
|
136
|
+
* `checkReplicaStatus` unchanged (HeyGen: the `avatar_group_id` — consent
|
|
137
|
+
* status lives on the group, not the individual look/replica).
|
|
138
|
+
*/
|
|
139
|
+
providerRef?: string;
|
|
140
|
+
}
|
|
141
|
+
export interface ReplicaTrainingStatus {
|
|
142
|
+
status: "training" | "pending_consent" | "ready" | "failed";
|
|
143
|
+
errorMessage?: string;
|
|
144
|
+
}
|
|
123
145
|
/** Engine can train a likeness replica from user media (HeyGen instant avatar, Tavus replica). */
|
|
124
146
|
export interface ISupportsReplica {
|
|
125
|
-
createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<CreateReplicaResult>;
|
|
148
|
+
/** `providerRef` is whatever `createReplica` returned as `providerRef` — pass it back unchanged. */
|
|
149
|
+
checkReplicaStatus(replicaId: string, providerRef?: string): Promise<ReplicaTrainingStatus>;
|
|
128
150
|
}
|
|
129
151
|
/** Engine can dub an existing video into another language (Tavus — our multilingual wedge). */
|
|
130
152
|
export interface ISupportsDubbing {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IAvatarVideoProvider.d.ts","sourceRoot":"","sources":["../../../src/services/avatarGen/IAvatarVideoProvider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"IAvatarVideoProvider.d.ts","sourceRoot":"","sources":["../../../src/services/avatarGen/IAvatarVideoProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,8 @@ function supportsHostedCatalog(p) {
|
|
|
35
35
|
typeof p.listVoices === "function");
|
|
36
36
|
}
|
|
37
37
|
function supportsReplica(p) {
|
|
38
|
-
return typeof p.createReplica === "function"
|
|
38
|
+
return (typeof p.createReplica === "function" &&
|
|
39
|
+
typeof p.checkReplicaStatus === "function");
|
|
39
40
|
}
|
|
40
41
|
function supportsDubbing(p) {
|
|
41
42
|
return typeof p.dub === "function";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EVideoGenModels } from "../../../globals/aiModels";
|
|
2
|
-
import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, EAvatarEngine, IAvatarVideoProvider, ISupportsHostedCatalog, VoiceOption } from "../IAvatarVideoProvider";
|
|
2
|
+
import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, ConsentRecord, CreateReplicaResult, EAvatarEngine, IAvatarVideoProvider, ISupportsHostedCatalog, ISupportsReplica, ReplicaTrainingStatus, VoiceOption } from "../IAvatarVideoProvider";
|
|
3
3
|
/**
|
|
4
4
|
* HeyGen avatar engine — a HOSTED engine (the caller picks a HeyGen-hosted
|
|
5
5
|
* avatar + voice and supplies a script; HeyGen does its own TTS + lipsync).
|
|
@@ -20,8 +20,27 @@ import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQu
|
|
|
20
20
|
* Capabilities: inputMode "hosted", nativeTts true (HeyGen synthesizes), no
|
|
21
21
|
* multi-scene split (one render per script). It also exposes the hosted catalog
|
|
22
22
|
* (ISupportsHostedCatalog) so the UI / agent can list pickable avatars + voices.
|
|
23
|
+
*
|
|
24
|
+
* Also implements ISupportsReplica — training a "digital twin" from user
|
|
25
|
+
* footage (HeyGen API, verified 2026-09-17 against developers.heygen.com's
|
|
26
|
+
* current v3 avatar docs; v2 above stays on v2 per its own sunset window,
|
|
27
|
+
* training only exists on v3):
|
|
28
|
+
* • train : POST /v3/avatars { type: "digital_twin", name, file: { type:
|
|
29
|
+
* "url", url } } → { data: { avatar_item: { id, status }, //
|
|
30
|
+
* avatar_group: { id, status, consent_status } } }. `avatar_item.id`
|
|
31
|
+
* (a "look") is the id rendered with; `avatar_group.id` owns consent.
|
|
32
|
+
* • consent : POST /v3/avatars/{group_id}/consent {} → { data: { url } } —
|
|
33
|
+
* a hosted webcam consent page, valid 24h, the subject must open.
|
|
34
|
+
* Uploading a pre-recorded consent clip instead (skipping the
|
|
35
|
+
* hosted page) is an enterprise-only tier we don't assume here.
|
|
36
|
+
* • status : GET /v3/avatars/looks/{look_id} → { data: { status: processing|
|
|
37
|
+
* completed|failed, error } } for training, then GET
|
|
38
|
+
* /v3/avatars/{group_id} → { data: { status: pending_consent|
|
|
39
|
+
* completed|failed } } for consent — training gates first, then
|
|
40
|
+
* consent (this is why checkReplicaStatus needs `providerRef`,
|
|
41
|
+
* the group id, in addition to the look id).
|
|
23
42
|
*/
|
|
24
|
-
export declare class HeyGenAvatarProvider implements IAvatarVideoProvider, ISupportsHostedCatalog {
|
|
43
|
+
export declare class HeyGenAvatarProvider implements IAvatarVideoProvider, ISupportsHostedCatalog, ISupportsReplica {
|
|
25
44
|
private readonly modelKey;
|
|
26
45
|
/** Static so callers can branch on capability without constructing (which
|
|
27
46
|
* would require HEYGEN_API_KEY just to read the input mode). */
|
|
@@ -35,6 +54,8 @@ export declare class HeyGenAvatarProvider implements IAvatarVideoProvider, ISupp
|
|
|
35
54
|
constructor(modelKey?: EVideoGenModels);
|
|
36
55
|
generate(req: AvatarGenerateRequest): Promise<AvatarSubmitResult>;
|
|
37
56
|
checkStatus(query: AvatarStatusQuery): Promise<AvatarStatusResult>;
|
|
57
|
+
createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<CreateReplicaResult>;
|
|
58
|
+
checkReplicaStatus(replicaId: string, providerRef?: string): Promise<ReplicaTrainingStatus>;
|
|
38
59
|
listAvatars(): Promise<AvatarOption[]>;
|
|
39
60
|
listVoices(): Promise<VoiceOption[]>;
|
|
40
61
|
private normalizeGender;
|
|
@@ -1 +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
|
|
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,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,oBACX,YAAW,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB;IAmBvE,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,aAAa,CACjB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,mBAAmB,CAAC;IA+CzB,kBAAkB,CACtB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,qBAAqB,CAAC;IA2C3B,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"}
|
|
@@ -30,6 +30,25 @@ const IAvatarVideoProvider_1 = require("../IAvatarVideoProvider");
|
|
|
30
30
|
* Capabilities: inputMode "hosted", nativeTts true (HeyGen synthesizes), no
|
|
31
31
|
* multi-scene split (one render per script). It also exposes the hosted catalog
|
|
32
32
|
* (ISupportsHostedCatalog) so the UI / agent can list pickable avatars + voices.
|
|
33
|
+
*
|
|
34
|
+
* Also implements ISupportsReplica — training a "digital twin" from user
|
|
35
|
+
* footage (HeyGen API, verified 2026-09-17 against developers.heygen.com's
|
|
36
|
+
* current v3 avatar docs; v2 above stays on v2 per its own sunset window,
|
|
37
|
+
* training only exists on v3):
|
|
38
|
+
* • train : POST /v3/avatars { type: "digital_twin", name, file: { type:
|
|
39
|
+
* "url", url } } → { data: { avatar_item: { id, status }, //
|
|
40
|
+
* avatar_group: { id, status, consent_status } } }. `avatar_item.id`
|
|
41
|
+
* (a "look") is the id rendered with; `avatar_group.id` owns consent.
|
|
42
|
+
* • consent : POST /v3/avatars/{group_id}/consent {} → { data: { url } } —
|
|
43
|
+
* a hosted webcam consent page, valid 24h, the subject must open.
|
|
44
|
+
* Uploading a pre-recorded consent clip instead (skipping the
|
|
45
|
+
* hosted page) is an enterprise-only tier we don't assume here.
|
|
46
|
+
* • status : GET /v3/avatars/looks/{look_id} → { data: { status: processing|
|
|
47
|
+
* completed|failed, error } } for training, then GET
|
|
48
|
+
* /v3/avatars/{group_id} → { data: { status: pending_consent|
|
|
49
|
+
* completed|failed } } for consent — training gates first, then
|
|
50
|
+
* consent (this is why checkReplicaStatus needs `providerRef`,
|
|
51
|
+
* the group id, in addition to the look id).
|
|
33
52
|
*/
|
|
34
53
|
class HeyGenAvatarProvider {
|
|
35
54
|
constructor(modelKey = aiModels_1.EVideoGenModels.HEYGEN_AVATAR) {
|
|
@@ -94,6 +113,58 @@ class HeyGenAvatarProvider {
|
|
|
94
113
|
}
|
|
95
114
|
return { status: types_1.EVideoSceneStatus.PENDING };
|
|
96
115
|
}
|
|
116
|
+
// ─── ISupportsReplica ─────────────────────────────────────────────────────
|
|
117
|
+
async createReplica(trainingMediaUrl, consent) {
|
|
118
|
+
const createData = await this.request("/v3/avatars", "POST", {
|
|
119
|
+
type: "digital_twin",
|
|
120
|
+
name: `vidspot-${consent.userId}-${consent.capturedAt}`,
|
|
121
|
+
file: { type: "url", url: trainingMediaUrl },
|
|
122
|
+
}, this.submitTimeout);
|
|
123
|
+
const lookId = createData?.data?.avatar_item?.id;
|
|
124
|
+
const groupId = createData?.data?.avatar_group?.id;
|
|
125
|
+
if (!lookId || !groupId) {
|
|
126
|
+
throw new Error(`HeyGen createReplica returned no avatar_item/avatar_group id: ${JSON.stringify(createData?.error ?? createData)}`);
|
|
127
|
+
}
|
|
128
|
+
// Kick off the hosted webcam consent flow immediately — the link is only
|
|
129
|
+
// valid 24h, so surface it to the caller right away rather than waiting
|
|
130
|
+
// for training (which runs independently) to finish first.
|
|
131
|
+
const consentData = await this.request(`/v3/avatars/${encodeURIComponent(groupId)}/consent`, "POST", {}, this.submitTimeout);
|
|
132
|
+
const consentUrl = consentData?.data?.url;
|
|
133
|
+
if (!consentUrl) {
|
|
134
|
+
logger_1.logger.warn("HeyGenAvatarProvider.createReplica: no consent url returned — training will proceed but the subject cannot approve consent yet", { groupId, response: consentData });
|
|
135
|
+
}
|
|
136
|
+
return { replicaId: lookId, providerRef: groupId, consentUrl };
|
|
137
|
+
}
|
|
138
|
+
async checkReplicaStatus(replicaId, providerRef) {
|
|
139
|
+
if (!providerRef) {
|
|
140
|
+
throw new Error("HeyGenAvatarProvider.checkReplicaStatus requires providerRef (the avatar_group_id returned by createReplica)");
|
|
141
|
+
}
|
|
142
|
+
const lookData = await this.requestWithRetry(`/v3/avatars/looks/${encodeURIComponent(replicaId)}`, "GET", undefined, this.statusTimeout);
|
|
143
|
+
const lookStatus = lookData?.data?.status;
|
|
144
|
+
if (lookStatus === "failed") {
|
|
145
|
+
return {
|
|
146
|
+
status: "failed",
|
|
147
|
+
errorMessage: lookData?.data?.error?.message ?? "HeyGen digital twin training failed",
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (lookStatus !== "completed") {
|
|
151
|
+
return { status: "training" };
|
|
152
|
+
}
|
|
153
|
+
// Training is done — now the gate is consent, which lives on the group.
|
|
154
|
+
const groupData = await this.requestWithRetry(`/v3/avatars/${encodeURIComponent(providerRef)}`, "GET", undefined, this.statusTimeout);
|
|
155
|
+
const groupStatus = groupData?.data?.status;
|
|
156
|
+
if (groupStatus === "completed") {
|
|
157
|
+
return { status: "ready" };
|
|
158
|
+
}
|
|
159
|
+
if (groupStatus === "failed") {
|
|
160
|
+
return {
|
|
161
|
+
status: "failed",
|
|
162
|
+
errorMessage: groupData?.data?.error?.message ?? "Avatar consent was rejected",
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// "pending_consent" (or HeyGen hasn't materialized a status yet).
|
|
166
|
+
return { status: "pending_consent" };
|
|
167
|
+
}
|
|
97
168
|
// ─── ISupportsHostedCatalog ───────────────────────────────────────────────
|
|
98
169
|
async listAvatars() {
|
|
99
170
|
const data = await this.requestWithRetry("/v2/avatars", "GET", undefined, this.statusTimeout);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EVideoGenModels } from "../../../globals/aiModels";
|
|
2
|
-
import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, ConsentRecord, EAvatarEngine, IAvatarVideoProvider, ISupportsHostedCatalog, ISupportsReplica, VoiceOption } from "../IAvatarVideoProvider";
|
|
2
|
+
import { AvatarCapabilities, AvatarGenerateRequest, AvatarOption, AvatarStatusQuery, AvatarStatusResult, AvatarSubmitResult, ConsentRecord, CreateReplicaResult, EAvatarEngine, IAvatarVideoProvider, ISupportsHostedCatalog, ISupportsReplica, ReplicaTrainingStatus, VoiceOption } from "../IAvatarVideoProvider";
|
|
3
3
|
/**
|
|
4
4
|
* Tavus avatar engine — a HOSTED engine driven by a trained "replica"
|
|
5
5
|
* (Tavus's term for a likeness model). The caller supplies a replica_id + a
|
|
@@ -39,9 +39,8 @@ export declare class TavusAvatarProvider implements IAvatarVideoProvider, ISuppo
|
|
|
39
39
|
constructor(modelKey?: EVideoGenModels);
|
|
40
40
|
generate(req: AvatarGenerateRequest): Promise<AvatarSubmitResult>;
|
|
41
41
|
checkStatus(query: AvatarStatusQuery): Promise<AvatarStatusResult>;
|
|
42
|
-
createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<
|
|
43
|
-
|
|
44
|
-
}>;
|
|
42
|
+
createReplica(trainingMediaUrl: string, consent: ConsentRecord): Promise<CreateReplicaResult>;
|
|
43
|
+
checkReplicaStatus(replicaId: string): Promise<ReplicaTrainingStatus>;
|
|
45
44
|
/** For Tavus the catalog of "avatars" is the account's trained replicas. */
|
|
46
45
|
listAvatars(): Promise<AvatarOption[]>;
|
|
47
46
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tavusAvatarProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/avatarGen/providers/tavusAvatarProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBACX,YAAW,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB;IAmBvE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAjB3B;oEACgE;IAChE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAI9C;IAEF,QAAQ,CAAC,MAAM,uBAAuB;IACtC,QAAQ,CAAC,YAAY,qBAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAGrB,QAAQ,GAAE,eAA8C;IAQrE,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA4BjE,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiClE,aAAa,CACjB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tavusAvatarProvider.d.ts","sourceRoot":"","sources":["../../../../src/services/avatarGen/providers/tavusAvatarProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBACX,YAAW,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB;IAmBvE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAjB3B;oEACgE;IAChE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAI9C;IAEF,QAAQ,CAAC,MAAM,uBAAuB;IACtC,QAAQ,CAAC,YAAY,qBAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAGrB,QAAQ,GAAE,eAA8C;IAQrE,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA4BjE,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiClE,aAAa,CACjB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,mBAAmB,CAAC;IA2BzB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAsB3E,4EAA4E;IACtE,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAgB5C;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAM5B,OAAO;YA0BP,gBAAgB;CAiE/B"}
|
|
@@ -95,8 +95,25 @@ class TavusAvatarProvider {
|
|
|
95
95
|
if (!data?.replica_id) {
|
|
96
96
|
throw new Error(`Tavus createReplica returned no replica_id: ${JSON.stringify(data)}`);
|
|
97
97
|
}
|
|
98
|
+
// Tavus bakes consent into the training call itself (consent_video_url
|
|
99
|
+
// above) — no separate out-of-band consent step, unlike HeyGen.
|
|
98
100
|
return { replicaId: data.replica_id };
|
|
99
101
|
}
|
|
102
|
+
async checkReplicaStatus(replicaId) {
|
|
103
|
+
// Single-replica GET is not list-wrapped (mirrors /v2/videos/{id} below).
|
|
104
|
+
const data = await this.requestWithRetry(`/v2/replicas/${encodeURIComponent(replicaId)}`, "GET", undefined, this.statusTimeout);
|
|
105
|
+
// Tavus replica status enum: started | completed | error.
|
|
106
|
+
if (data?.status === "completed") {
|
|
107
|
+
return { status: "ready" };
|
|
108
|
+
}
|
|
109
|
+
if (data?.status === "error") {
|
|
110
|
+
return {
|
|
111
|
+
status: "failed",
|
|
112
|
+
errorMessage: data.error_message ?? "Tavus replica training failed",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return { status: "training" };
|
|
116
|
+
}
|
|
100
117
|
// ─── ISupportsHostedCatalog ───────────────────────────────────────────────
|
|
101
118
|
/** For Tavus the catalog of "avatars" is the account's trained replicas. */
|
|
102
119
|
async listAvatars() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planToProject.d.ts","sourceRoot":"","sources":["../../../src/services/editor/planToProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKV,OAAO,EAIR,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAehE,OAAO,EAAE,QAAQ,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"planToProject.d.ts","sourceRoot":"","sources":["../../../src/services/editor/planToProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKV,OAAO,EAIR,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAehE,OAAO,EAAE,QAAQ,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAOpF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAsdhE"}
|
|
@@ -11,6 +11,10 @@ var planToProject_helpers_2 = require("./planToProject.helpers");
|
|
|
11
11
|
Object.defineProperty(exports, "TRACK_ID", { enumerable: true, get: function () { return planToProject_helpers_2.TRACK_ID; } });
|
|
12
12
|
Object.defineProperty(exports, "buildOverlayClipsForScene", { enumerable: true, get: function () { return planToProject_helpers_2.buildOverlayClipsForScene; } });
|
|
13
13
|
Object.defineProperty(exports, "PLACEHOLDER_URL", { enumerable: true, get: function () { return planToProject_helpers_2.PLACEHOLDER_URL; } });
|
|
14
|
+
// Reach per-recipient website-screenshot opening scene (see plan.websiteScreenshotUrl
|
|
15
|
+
// below) — a fixed-length title-card scene, long enough to register as a distinct
|
|
16
|
+
// beat but short enough not to delay the pitch.
|
|
17
|
+
const WEBSITE_OPENING_SCENE_DURATION_MS = 3000;
|
|
14
18
|
/**
|
|
15
19
|
* planToProject — pure translator from an approved VideoPlan + per-scene
|
|
16
20
|
* executor outcomes into the canonical Project IR. The Project is what gets
|
|
@@ -40,12 +44,36 @@ function planToProject(input) {
|
|
|
40
44
|
// Walk scenes in order; build clips per kind and accumulate offset.
|
|
41
45
|
const clips = [];
|
|
42
46
|
const transitions = [];
|
|
43
|
-
let offsetMs = 0;
|
|
44
47
|
let prevVisualClipId = null;
|
|
45
48
|
let hasVoiceover = false;
|
|
46
49
|
let hasOverlays = false;
|
|
47
50
|
let hasCaptions = false;
|
|
48
51
|
let hasBroll = false;
|
|
52
|
+
// Reach per-recipient website screenshot — a genuine LEADING scene (its own
|
|
53
|
+
// time slice on the main visual track), not a spanning overlay like the logo
|
|
54
|
+
// below. Only emitted when the outreach fan-out injected
|
|
55
|
+
// plan.websiteScreenshotUrl (the planner never sets it); every other scene's
|
|
56
|
+
// display.from/to shifts automatically since offsetMs starts past it.
|
|
57
|
+
let offsetMs = 0;
|
|
58
|
+
if (plan.websiteScreenshotUrl) {
|
|
59
|
+
const openingClip = {
|
|
60
|
+
id: "website-opening",
|
|
61
|
+
trackId: planToProject_helpers_1.TRACK_ID.visual,
|
|
62
|
+
type: "image",
|
|
63
|
+
display: { from: 0, to: WEBSITE_OPENING_SCENE_DURATION_MS },
|
|
64
|
+
name: "Website",
|
|
65
|
+
src: plan.websiteScreenshotUrl,
|
|
66
|
+
fit: "cover",
|
|
67
|
+
provenance: { tier: "T0", source: "website-screenshot", creditsSpent: 0 },
|
|
68
|
+
effects: [],
|
|
69
|
+
transform: { x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0, opacity: 1 },
|
|
70
|
+
locked: false,
|
|
71
|
+
metadata: { websiteOpening: true },
|
|
72
|
+
};
|
|
73
|
+
clips.push(openingClip);
|
|
74
|
+
prevVisualClipId = openingClip.id;
|
|
75
|
+
offsetMs = WEBSITE_OPENING_SCENE_DURATION_MS;
|
|
76
|
+
}
|
|
49
77
|
const sortedScenes = [...plan.scenes].sort((a, b) => a.sceneIndex - b.sceneIndex);
|
|
50
78
|
for (const scene of sortedScenes) {
|
|
51
79
|
const outcome = outcomes[scene.sceneIndex];
|
|
@@ -18,6 +18,7 @@ import { IVideoQaJobModel } from "../models/videoQaJob.model";
|
|
|
18
18
|
import { IGithubConnectionModel } from "../models/githubConnection.model";
|
|
19
19
|
import { IProductConnectionModel } from "../models/productConnection.model";
|
|
20
20
|
import { IOutreachCampaignModel, IOutreachRecipientModel, IOutreachTemplateModel, IPersonalizedVideoModel, IVideoViewModel } from "../models/outreach.model";
|
|
21
|
+
import { IApiKeyModel, IWebhookSubscriptionModel } from "../models/outreachIntegration.model";
|
|
21
22
|
import { IOrganizationCreditLedgerEntry, IOrganizationInviteModel, IOrganizationMemberModel, IOrganizationModel } from "../models/organization.model";
|
|
22
23
|
/**
|
|
23
24
|
* FirestoreService
|
|
@@ -83,6 +84,8 @@ export declare class FirestoreService {
|
|
|
83
84
|
static outreachCampaignsCol: CollectionReference<IOutreachCampaignModel, DocumentData>;
|
|
84
85
|
static outreachRecipientsCol: CollectionReference<IOutreachRecipientModel, DocumentData>;
|
|
85
86
|
static videoViewsCol: CollectionReference<IVideoViewModel, DocumentData>;
|
|
87
|
+
static apiKeysCol: CollectionReference<IApiKeyModel, DocumentData>;
|
|
88
|
+
static webhookSubscriptionsCol: CollectionReference<IWebhookSubscriptionModel, DocumentData>;
|
|
86
89
|
static organizationsCol: CollectionReference<IOrganizationModel, DocumentData>;
|
|
87
90
|
static organizationMembersCol: CollectionReference<IOrganizationMemberModel, DocumentData>;
|
|
88
91
|
static organizationInvitesCol: CollectionReference<IOrganizationInviteModel, DocumentData>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestore.service.d.ts","sourceRoot":"","sources":["../../src/services/firestore.service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"firestore.service.d.ts","sourceRoot":"","sources":["../../src/services/firestore.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -220,6 +220,13 @@ FirestoreService.outreachRecipientsCol = firebase_1.firestore
|
|
|
220
220
|
FirestoreService.videoViewsCol = firebase_1.firestore
|
|
221
221
|
.collection("videoViews")
|
|
222
222
|
.withConverter(collectionConverter());
|
|
223
|
+
// Reach Phase 7 — self-serve API integration
|
|
224
|
+
FirestoreService.apiKeysCol = firebase_1.firestore
|
|
225
|
+
.collection("apiKeys")
|
|
226
|
+
.withConverter(collectionConverter());
|
|
227
|
+
FirestoreService.webhookSubscriptionsCol = firebase_1.firestore
|
|
228
|
+
.collection("webhookSubscriptions")
|
|
229
|
+
.withConverter(collectionConverter());
|
|
223
230
|
// Enterprise: Organizations & Team Members
|
|
224
231
|
FirestoreService.organizationsCol = firebase_1.firestore
|
|
225
232
|
.collection("organizations")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadAudioBuffer.d.ts","sourceRoot":"","sources":["../../../src/services/gcp/uploadAudioBuffer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"uploadAudioBuffer.d.ts","sourceRoot":"","sources":["../../../src/services/gcp/uploadAudioBuffer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,MAAM,CAAC,CAcjB"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.uploadAudioBufferToGcs = uploadAudioBufferToGcs;
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
5
|
const firebase_1 = require("../../libs/firebase");
|
|
6
|
+
const storage_1 = require("../../libs/storage");
|
|
6
7
|
/**
|
|
7
8
|
* Uploads an audio buffer to the project's Firebase Storage bucket and
|
|
8
9
|
* returns a public download URL. Used by the agent VO pipeline: ElevenLabs
|
|
@@ -24,5 +25,8 @@ async function uploadAudioBufferToGcs(buffer, destination, contentType = "audio/
|
|
|
24
25
|
metadata: { firebaseStorageDownloadTokens: downloadToken },
|
|
25
26
|
},
|
|
26
27
|
});
|
|
28
|
+
// mediaStorage: best-effort R2 mirror (zero-egress delivery). GCS keeps the
|
|
29
|
+
// firebaseStorage download-token URL as the stored system-of-record URL.
|
|
30
|
+
await storage_1.mediaStorage.mirrorBytes(destination, buffer, contentType);
|
|
27
31
|
return `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURIComponent(destination)}?alt=media&token=${downloadToken}`;
|
|
28
32
|
}
|
package/lib/services/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./firestore.service";
|
|
|
5
5
|
export * from "./aiGen";
|
|
6
6
|
export * from "./avatarGen";
|
|
7
7
|
export * from "./bullmq.service";
|
|
8
|
+
export * from "./outreachWebhooks.service";
|
|
8
9
|
export * from "./gcp";
|
|
9
10
|
export * from "./credit.service";
|
|
10
11
|
export * from "./notification.service";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,SAAS,CAAC"}
|
package/lib/services/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./firestore.service"), exports);
|
|
|
21
21
|
__exportStar(require("./aiGen"), exports);
|
|
22
22
|
__exportStar(require("./avatarGen"), exports);
|
|
23
23
|
__exportStar(require("./bullmq.service"), exports);
|
|
24
|
+
__exportStar(require("./outreachWebhooks.service"), exports);
|
|
24
25
|
__exportStar(require("./gcp"), exports);
|
|
25
26
|
__exportStar(require("./credit.service"), exports);
|
|
26
27
|
__exportStar(require("./notification.service"), exports);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { OutreachWebhookEvent } from "../models/outreachIntegration.model";
|
|
2
|
+
/**
|
|
3
|
+
* VidSpot Reach — Phase 7 self-serve API integration. Payload for one
|
|
4
|
+
* webhook-delivery job (one job per active subscriber per event); the worker
|
|
5
|
+
* (apps/node-express-server) owns the signed HTTP POST + BullMQ's own
|
|
6
|
+
* attempts/backoff drive retry.
|
|
7
|
+
*/
|
|
8
|
+
export interface WebhookDeliveryJobPayload {
|
|
9
|
+
subscriptionId: string;
|
|
10
|
+
event: OutreachWebhookEvent;
|
|
11
|
+
data: Record<string, unknown>;
|
|
12
|
+
deliveryId: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fan out one webhook-delivery job per ACTIVE subscriber of `event` for
|
|
16
|
+
* `userId`. Best-effort: a lookup/enqueue failure is logged and swallowed so
|
|
17
|
+
* it never blocks the caller's own state transition — campaign completion,
|
|
18
|
+
* video finalization, and view recording all proceed regardless of webhook
|
|
19
|
+
* health. Called from the three Reach event sources: outreachCampaignProcessor
|
|
20
|
+
* / outreachReconcile (campaign.completed, video.ready) and
|
|
21
|
+
* publicOutreach.controller's recordViewEvent (recipient.viewed).
|
|
22
|
+
*/
|
|
23
|
+
export declare function dispatchOutreachWebhookEvent(userId: string, event: OutreachWebhookEvent, data: Record<string, unknown>): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=outreachWebhooks.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outreachWebhooks.service.d.ts","sourceRoot":"","sources":["../../src/services/outreachWebhooks.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAK3E;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dispatchOutreachWebhookEvent = dispatchOutreachWebhookEvent;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const types_1 = require("../globals/types");
|
|
6
|
+
const logger_1 = require("../utils/logger");
|
|
7
|
+
const bullmq_service_1 = require("./bullmq.service");
|
|
8
|
+
const firestore_service_1 = require("./firestore.service");
|
|
9
|
+
/**
|
|
10
|
+
* Fan out one webhook-delivery job per ACTIVE subscriber of `event` for
|
|
11
|
+
* `userId`. Best-effort: a lookup/enqueue failure is logged and swallowed so
|
|
12
|
+
* it never blocks the caller's own state transition — campaign completion,
|
|
13
|
+
* video finalization, and view recording all proceed regardless of webhook
|
|
14
|
+
* health. Called from the three Reach event sources: outreachCampaignProcessor
|
|
15
|
+
* / outreachReconcile (campaign.completed, video.ready) and
|
|
16
|
+
* publicOutreach.controller's recordViewEvent (recipient.viewed).
|
|
17
|
+
*/
|
|
18
|
+
async function dispatchOutreachWebhookEvent(userId, event, data) {
|
|
19
|
+
try {
|
|
20
|
+
const snap = await firestore_service_1.FirestoreService.webhookSubscriptionsCol
|
|
21
|
+
.where("userId", "==", userId)
|
|
22
|
+
.where("active", "==", true)
|
|
23
|
+
.where("events", "array-contains", event)
|
|
24
|
+
.get();
|
|
25
|
+
if (snap.empty)
|
|
26
|
+
return;
|
|
27
|
+
await Promise.all(snap.docs.map((doc) => bullmq_service_1.bullmq.addJob(types_1.ERedisQueues.WEBHOOK_DELIVERY_JOBS, {
|
|
28
|
+
subscriptionId: doc.id,
|
|
29
|
+
event,
|
|
30
|
+
data,
|
|
31
|
+
deliveryId: (0, crypto_1.randomUUID)(),
|
|
32
|
+
}, { attempts: 5, backoff: { type: "exponential", delay: 5000 } })));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
logger_1.logger.warn("dispatchOutreachWebhookEvent: fan-out failed", {
|
|
36
|
+
userId,
|
|
37
|
+
event,
|
|
38
|
+
err: err instanceof Error ? err.message : String(err),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|