@happyvertical/smrt-video 0.30.0

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.
@@ -0,0 +1,1277 @@
1
+ import { Asset } from '@happyvertical/smrt-assets';
2
+ import { AssetOptions } from '@happyvertical/smrt-assets';
3
+ import { Content } from '@happyvertical/smrt-content';
4
+ import { ContentOptions } from '@happyvertical/smrt-content';
5
+ import { MediaBundleFileDescriptor } from '@happyvertical/smrt-assets';
6
+ import { MediaBundleGpsTrackPoint } from '@happyvertical/smrt-assets';
7
+ import { MediaBundleInspection } from '@happyvertical/smrt-assets';
8
+ import { MediaBundleInspectionLike } from '@happyvertical/smrt-assets';
9
+ import { MediaBundleNormalizedMetadata } from '@happyvertical/smrt-assets';
10
+ import { MediaBundleSupportFileInspection } from '@happyvertical/smrt-assets';
11
+ import { MediaSupportFileVisibility } from '@happyvertical/smrt-assets';
12
+ import { PersistMediaBundleAssetInput } from '@happyvertical/smrt-assets';
13
+ import { PersistMediaBundleAssociationInput } from '@happyvertical/smrt-assets';
14
+ import { persistMediaBundleInspection } from '@happyvertical/smrt-assets';
15
+ import { PersistMediaBundleInspectionOptions } from '@happyvertical/smrt-assets';
16
+ import { PersistMediaBundleInspectionResult } from '@happyvertical/smrt-assets';
17
+ import { PersistMediaBundleMetadataArtifactInput } from '@happyvertical/smrt-assets';
18
+ import { SmrtCollection } from '@happyvertical/smrt-core';
19
+ import { SmrtJunction } from '@happyvertical/smrt-core';
20
+ import { SmrtMediaBundlePersistenceAdapter } from '@happyvertical/smrt-assets';
21
+ import { SmrtObject } from '@happyvertical/smrt-core';
22
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
23
+ import { WordTiming } from '@happyvertical/smrt-voice';
24
+
25
+ /**
26
+ * Anchor point for character placement in scene
27
+ */
28
+ export declare interface AnchorPoint {
29
+ /** Anchor point identifier */
30
+ id: string;
31
+ /** Human-readable name */
32
+ name: string;
33
+ /** Position as normalized coordinates (0-1) */
34
+ position: {
35
+ x: number;
36
+ y: number;
37
+ };
38
+ /** Suggested character scale at this point */
39
+ suggestedScale: number;
40
+ /** Ground plane Y coordinate for perspective */
41
+ groundY: number;
42
+ /** Optional viewpoint this anchor belongs to */
43
+ viewpointId?: string;
44
+ }
45
+
46
+ /**
47
+ * Branding configuration for video overlays
48
+ */
49
+ export declare interface BrandingConfig {
50
+ /** Asset ID for logo overlay */
51
+ logoAssetId?: string | null;
52
+ /** Primary brand color (hex) */
53
+ primaryColor?: string | null;
54
+ /** Background color (hex) */
55
+ backgroundColor?: string | null;
56
+ /** Lower-third template name */
57
+ lowerThirdTemplate?: string | null;
58
+ /** Font family for text overlays */
59
+ fontFamily?: string | null;
60
+ /** Whether to show news ticker */
61
+ tickerEnabled?: boolean;
62
+ }
63
+
64
+ /**
65
+ * Virtual character for AI-powered video production
66
+ *
67
+ * Character represents a virtual persona combining:
68
+ * - Visual identity: Seed image for I2V (image-to-video) generation
69
+ * - Voice identity: Link to a VoiceProfile for TTS
70
+ * - Branding: Logo overlays, lower-thirds, colors
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { Character } from '@happyvertical/smrt-video';
75
+ *
76
+ * const character = new Character({
77
+ * name: 'Bentley News Anchor',
78
+ * description: 'Professional news anchor for local broadcasts',
79
+ * imageAssetId: 'asset-123',
80
+ * voiceProfileId: 'voice-456',
81
+ * brandingKit: {
82
+ * logoAssetId: 'asset-789',
83
+ * primaryColor: '#1a73e8',
84
+ * lowerThirdTemplate: 'news-standard',
85
+ * tickerEnabled: true,
86
+ * },
87
+ * });
88
+ * await character.save();
89
+ * ```
90
+ */
91
+ declare class Character extends SmrtObject {
92
+ /** Tenant ID for multi-tenant isolation */
93
+ tenantId: string | null;
94
+ /** Human-readable name for the character */
95
+ name: string;
96
+ /** Description of the character persona */
97
+ description: string | null;
98
+ /** Asset ID of the seed image for I2V generation */
99
+ imageAssetId: string | null;
100
+ /** Asset ID of pre-baked base motion video */
101
+ baseMotionAssetId: string | null;
102
+ /** Voice profile ID for speech synthesis */
103
+ voiceProfileId: string | null;
104
+ /** Branding configuration for video overlays */
105
+ brandingKit: BrandingConfig;
106
+ /** Character status */
107
+ status: CharacterStatus;
108
+ /** Linked performer for IP-Adapter face consistency */
109
+ performerId: string | null;
110
+ /** Default scene for this character */
111
+ defaultSceneId: string | null;
112
+ /** Scene-specific configurations */
113
+ sceneConfigs: CharacterSceneConfig[];
114
+ /** 1-1 profile record for this character */
115
+ profileId: string | null;
116
+ constructor(options?: CharacterOptions);
117
+ private getCharacterAssetCollection;
118
+ private getLegacyFieldAssetIds;
119
+ private setLegacyFieldAssetId;
120
+ private clearLegacyFieldAssetId;
121
+ getAssets(role?: CharacterAssetRole): Promise<Asset[]>;
122
+ getAssetByRole(role: CharacterAssetRole): Promise<Asset | null>;
123
+ addAsset(asset: Asset, role?: CharacterAssetRole, sortOrder?: number): Promise<void>;
124
+ removeAsset(assetId: string, role?: CharacterAssetRole): Promise<void>;
125
+ /**
126
+ * Check if the character has a pre-baked base motion video
127
+ * @deprecated Use getAssetByRole('base-motion') instead
128
+ */
129
+ get hasBaseMotion(): boolean;
130
+ /** Check if the character is complete and ready for video generation */
131
+ get isComplete(): boolean;
132
+ }
133
+ export { Character }
134
+ export { Character as PersonalityProfile }
135
+
136
+ export declare class CharacterAsset extends Asset {
137
+ characterId: string | null;
138
+ role: CharacterAssetRole;
139
+ constructor(options?: CharacterAssetOptions);
140
+ }
141
+
142
+ export declare interface CharacterAssetOptions extends AssetOptions {
143
+ /** Character this asset belongs to */
144
+ characterId?: string | null;
145
+ /** Role of this asset for the character */
146
+ role?: CharacterAssetRole;
147
+ }
148
+
149
+ /** Roles a character asset can play */
150
+ export declare type CharacterAssetRole = 'seed-image' | 'base-motion' | 'logo';
151
+
152
+ export declare class CharacterCollection extends SmrtCollection<Character> {
153
+ static readonly _itemClass: typeof Character;
154
+ /** Find all characters belonging to a specific tenant */
155
+ findByTenant(tenantId: string): Promise<Character[]>;
156
+ /** Find all global characters (without a tenant) */
157
+ findGlobal(): Promise<Character[]>;
158
+ /** Find characters by performer */
159
+ findByPerformer(performerId: string): Promise<Character[]>;
160
+ /** Find characters that are ready for video generation */
161
+ findReady(): Promise<Character[]>;
162
+ }
163
+
164
+ /**
165
+ * Character creation options
166
+ */
167
+ declare interface CharacterOptions extends SmrtObjectOptions {
168
+ /** Human-readable name for the character */
169
+ name?: string;
170
+ /** Description of the character persona */
171
+ description?: string | null;
172
+ /** Asset ID of the seed image for image-to-video generation */
173
+ imageAssetId?: string | null;
174
+ /** Asset ID of pre-baked base motion video */
175
+ baseMotionAssetId?: string | null;
176
+ /** Voice profile ID for speech synthesis */
177
+ voiceProfileId?: string | null;
178
+ /** Branding configuration for video overlays */
179
+ brandingKit?: BrandingConfig;
180
+ /** Character status */
181
+ status?: CharacterStatus;
182
+ /** Linked performer for IP-Adapter face consistency */
183
+ performerId?: string | null;
184
+ /** Default scene for this character */
185
+ defaultSceneId?: string | null;
186
+ /** Scene-specific configurations */
187
+ sceneConfigs?: CharacterSceneConfig[];
188
+ /** 1-1 profile record for this character */
189
+ profileId?: string | null;
190
+ /** Tenant ID for multi-tenant isolation */
191
+ tenantId?: string | null;
192
+ }
193
+ export { CharacterOptions }
194
+ export { CharacterOptions as PersonalityProfileOptions }
195
+
196
+ export declare class CharacterOwnedAsset extends SmrtObject {
197
+ tenantId: string | null;
198
+ characterId: string;
199
+ assetId: string;
200
+ role: CharacterAssetRole;
201
+ sortOrder: number;
202
+ constructor(options?: CharacterOwnedAssetOptions);
203
+ }
204
+
205
+ export declare class CharacterOwnedAssetCollection extends SmrtJunction<CharacterOwnedAsset> {
206
+ static readonly _itemClass: typeof CharacterOwnedAsset;
207
+ protected leftField: string;
208
+ protected rightField: string;
209
+ }
210
+
211
+ export declare interface CharacterOwnedAssetOptions extends SmrtObjectOptions {
212
+ characterId?: string;
213
+ assetId?: string;
214
+ role?: CharacterAssetRole;
215
+ sortOrder?: number;
216
+ tenantId?: string | null;
217
+ }
218
+
219
+ /**
220
+ * Scene-specific configuration for a character
221
+ */
222
+ export declare interface CharacterSceneConfig {
223
+ /** Scene ID */
224
+ sceneId: string;
225
+ /** Preferred viewpoint ID (for 360° scenes) */
226
+ viewpointId?: string;
227
+ /** Anchor point ID for placement */
228
+ anchorPointId?: string;
229
+ /** Character scale in this scene */
230
+ scale: number;
231
+ /** Character position in this scene (normalized 0-1) */
232
+ position: {
233
+ x: number;
234
+ y: number;
235
+ };
236
+ }
237
+
238
+ /**
239
+ * Character status
240
+ */
241
+ declare type CharacterStatus = 'pending' | 'ready';
242
+ export { CharacterStatus }
243
+ export { CharacterStatus as PersonalityProfileStatus }
244
+
245
+ /**
246
+ * Composite job for tracking virtual production compositing
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * import { CompositeJob } from '@happyvertical/smrt-video';
251
+ *
252
+ * const job = new CompositeJob({
253
+ * characterVideoAssetId: 'asset-video-123',
254
+ * sceneId: 'scene-townhall',
255
+ * scale: 0.8,
256
+ * position: { x: 0.5, y: 0.7 },
257
+ * });
258
+ * await job.save();
259
+ * ```
260
+ */
261
+ export declare class CompositeJob extends SmrtObject {
262
+ tenantId: string | null;
263
+ /** Character video asset ID (after lip-sync) */
264
+ characterVideoAssetId: string | null;
265
+ /** Scene ID to composite onto */
266
+ sceneId: string | null;
267
+ /** Viewpoint ID (for 360° scenes) */
268
+ viewpointId: string | null;
269
+ /** Anchor point ID for placement */
270
+ anchorPointId: string | null;
271
+ /** Character scale */
272
+ scale: number;
273
+ /** Character position (normalized 0-1) */
274
+ position: {
275
+ x: number;
276
+ y: number;
277
+ };
278
+ /** Job status */
279
+ status: CompositeJobStatus;
280
+ /** Progress percentage (0-100) */
281
+ progress: number;
282
+ /** Output video asset ID */
283
+ outputAssetId: string | null;
284
+ /** Error message if failed */
285
+ errorMessage: string | null;
286
+ constructor(options?: CompositeJobOptions);
287
+ /** Check if the job is complete */
288
+ get isComplete(): boolean;
289
+ /** Check if the job is in progress */
290
+ get isProcessing(): boolean;
291
+ }
292
+
293
+ /**
294
+ * Composite job creation options
295
+ */
296
+ export declare interface CompositeJobOptions extends SmrtObjectOptions {
297
+ /** Character video asset ID (after lip-sync) */
298
+ characterVideoAssetId?: string | null;
299
+ /** Scene ID to composite onto */
300
+ sceneId?: string | null;
301
+ /** Viewpoint ID (for 360° scenes) */
302
+ viewpointId?: string | null;
303
+ /** Anchor point ID for placement */
304
+ anchorPointId?: string | null;
305
+ /** Character scale */
306
+ scale?: number;
307
+ /** Character position (normalized 0-1) */
308
+ position?: {
309
+ x: number;
310
+ y: number;
311
+ };
312
+ /** Job status */
313
+ status?: CompositeJobStatus;
314
+ /** Progress percentage (0-100) */
315
+ progress?: number;
316
+ /** Output video asset ID */
317
+ outputAssetId?: string | null;
318
+ /** Error message if failed */
319
+ errorMessage?: string | null;
320
+ /** Tenant ID for multi-tenant isolation */
321
+ tenantId?: string | null;
322
+ }
323
+
324
+ /**
325
+ * Composite job status
326
+ */
327
+ export declare type CompositeJobStatus = 'pending' | 'removing_bg' | 'analyzing_light' | 'compositing' | 'complete' | 'failed';
328
+
329
+ /**
330
+ * Lighting profile for IC-Light matching
331
+ */
332
+ export declare interface LightingProfile {
333
+ /** Dominant light direction (normalized vector) */
334
+ direction?: {
335
+ x: number;
336
+ y: number;
337
+ z: number;
338
+ };
339
+ /** Light color temperature (Kelvin) */
340
+ colorTemperature?: number;
341
+ /** Ambient light intensity (0-1) */
342
+ ambientIntensity?: number;
343
+ /** Key light intensity (0-1) */
344
+ keyLightIntensity?: number;
345
+ /** Shadow softness (0-1) */
346
+ shadowSoftness?: number;
347
+ /** Environment map asset ID for reflections */
348
+ envMapAssetId?: string;
349
+ }
350
+
351
+ export { MediaBundleFileDescriptor }
352
+
353
+ export { MediaBundleGpsTrackPoint }
354
+
355
+ export { MediaBundleInspection }
356
+
357
+ export { MediaBundleInspectionLike }
358
+
359
+ export { MediaBundleNormalizedMetadata }
360
+
361
+ export { MediaBundleSupportFileInspection }
362
+
363
+ export { MediaSupportFileVisibility }
364
+
365
+ /**
366
+ * Node mapping for dynamic parameter injection
367
+ */
368
+ export declare interface NodeMapping {
369
+ /**
370
+ * Node ID for anchor seed image input
371
+ */
372
+ seedImage?: string;
373
+ /**
374
+ * Node ID for TTS audio input
375
+ */
376
+ audioFile?: string;
377
+ /**
378
+ * Node ID for base motion video input
379
+ */
380
+ baseVideo?: string;
381
+ /**
382
+ * Node ID for final video output
383
+ */
384
+ outputVideo?: string;
385
+ /**
386
+ * Node ID for text prompt input
387
+ */
388
+ prompt?: string;
389
+ /**
390
+ * Node ID for negative prompt input
391
+ */
392
+ negativePrompt?: string;
393
+ /**
394
+ * Node ID for sampler/scheduler settings
395
+ */
396
+ sampler?: string;
397
+ /**
398
+ * Node ID for video duration control
399
+ */
400
+ duration?: string;
401
+ /**
402
+ * Additional custom node mappings
403
+ */
404
+ [key: string]: string | undefined;
405
+ }
406
+
407
+ /**
408
+ * Performer - The physical likeness/face DNA
409
+ *
410
+ * A Performer represents a person's visual identity for consistent
411
+ * face generation across multiple Characters. One Performer can play
412
+ * many Characters (e.g., same face as "Evening Anchor" and "Weekend Host").
413
+ *
414
+ * @example
415
+ * ```typescript
416
+ * import { Performer } from '@happyvertical/smrt-video';
417
+ *
418
+ * const performer = new Performer({
419
+ * name: 'Alex Bentley',
420
+ * dna: {
421
+ * gender: 'male',
422
+ * ageRange: 'adult',
423
+ * ipAdapterWeight: 0.75,
424
+ * },
425
+ * referenceAssetIds: ['ref-img-1', 'ref-img-2'],
426
+ * });
427
+ * await performer.save();
428
+ * ```
429
+ */
430
+ export declare class Performer extends SmrtObject {
431
+ tenantId: string | null;
432
+ /** Human-readable name */
433
+ name: string;
434
+ /** Description */
435
+ description: string | null;
436
+ /** Performer DNA for consistent face generation */
437
+ dna: PerformerDNA;
438
+ /** Reference images for IP-Adapter (multiple angles/expressions) */
439
+ referenceAssetIds: string[];
440
+ /** Generated seed image asset ID */
441
+ seedImageAssetId: string | null;
442
+ /** Default voice profile for this performer */
443
+ voiceProfileId: string | null;
444
+ /** Performer status */
445
+ status: PerformerStatus;
446
+ /** 1-1 profile record for this performer */
447
+ profileId: string | null;
448
+ constructor(options?: PerformerOptions);
449
+ private getPerformerAssetCollection;
450
+ private getLegacyFieldAssetIds;
451
+ private setLegacyFieldAssetId;
452
+ private clearLegacyFieldAssetId;
453
+ getAssets(role?: PerformerAssetRole): Promise<Asset[]>;
454
+ getAssetByRole(role: PerformerAssetRole): Promise<Asset | null>;
455
+ addAsset(asset: Asset, role?: PerformerAssetRole, sortOrder?: number): Promise<void>;
456
+ removeAsset(assetId: string, role?: PerformerAssetRole): Promise<void>;
457
+ /** Check if the performer has reference images */
458
+ get hasReferences(): boolean;
459
+ /** Check if the performer has a face embedding */
460
+ get hasFaceEmbedding(): boolean;
461
+ /** Check if the performer is ready for generation */
462
+ get isReady(): boolean;
463
+ }
464
+
465
+ export declare class PerformerAsset extends Asset {
466
+ performerId: string | null;
467
+ role: PerformerAssetRole;
468
+ constructor(options?: PerformerAssetOptions);
469
+ }
470
+
471
+ export declare interface PerformerAssetOptions extends AssetOptions {
472
+ /** Performer this asset belongs to */
473
+ performerId?: string | null;
474
+ /** Role of this asset for the performer */
475
+ role?: PerformerAssetRole;
476
+ }
477
+
478
+ /** Roles a performer asset can play */
479
+ export declare type PerformerAssetRole = 'reference' | 'seed';
480
+
481
+ /**
482
+ * Performer DNA for IP-Adapter FaceID consistency
483
+ */
484
+ export declare interface PerformerDNA {
485
+ /** Gender */
486
+ gender: 'male' | 'female' | 'neutral';
487
+ /** Age range */
488
+ ageRange: 'child' | 'teen' | 'young_adult' | 'adult' | 'middle_aged' | 'senior';
489
+ /** Face embedding for IP-Adapter FaceID (512-dim vector) */
490
+ faceEmbedding?: number[];
491
+ /** Default clothing style (can be overridden per Character) */
492
+ defaultClothing?: {
493
+ style: 'business' | 'casual' | 'formal' | 'outdoor';
494
+ colors?: string[];
495
+ description?: string;
496
+ };
497
+ /** IP-Adapter weight for consistency (0.5-1.0) */
498
+ ipAdapterWeight: number;
499
+ /** FaceID weight for face consistency */
500
+ faceIdWeight?: number;
501
+ }
502
+
503
+ /**
504
+ * Performer creation options
505
+ */
506
+ export declare interface PerformerOptions extends SmrtObjectOptions {
507
+ /** Human-readable name */
508
+ name?: string;
509
+ /** Description */
510
+ description?: string | null;
511
+ /** Performer DNA for consistent face generation */
512
+ dna?: PerformerDNA;
513
+ /** Reference images for IP-Adapter (multiple angles/expressions) */
514
+ referenceAssetIds?: string[];
515
+ /** Generated seed image asset ID */
516
+ seedImageAssetId?: string | null;
517
+ /** Default voice profile for this performer */
518
+ voiceProfileId?: string | null;
519
+ /** Performer status */
520
+ status?: PerformerStatus;
521
+ /** 1-1 profile record for this performer */
522
+ profileId?: string | null;
523
+ /** Tenant ID for multi-tenant isolation */
524
+ tenantId?: string | null;
525
+ }
526
+
527
+ export declare class PerformerOwnedAsset extends SmrtObject {
528
+ tenantId: string | null;
529
+ performerId: string;
530
+ assetId: string;
531
+ role: PerformerAssetRole;
532
+ sortOrder: number;
533
+ constructor(options?: PerformerOwnedAssetOptions);
534
+ }
535
+
536
+ export declare class PerformerOwnedAssetCollection extends SmrtJunction<PerformerOwnedAsset> {
537
+ static readonly _itemClass: typeof PerformerOwnedAsset;
538
+ protected leftField: string;
539
+ protected rightField: string;
540
+ }
541
+
542
+ export declare interface PerformerOwnedAssetOptions extends SmrtObjectOptions {
543
+ performerId?: string;
544
+ assetId?: string;
545
+ role?: PerformerAssetRole;
546
+ sortOrder?: number;
547
+ tenantId?: string | null;
548
+ }
549
+
550
+ /**
551
+ * Performer status
552
+ */
553
+ export declare type PerformerStatus = 'pending' | 'ready';
554
+
555
+ export { PersistMediaBundleAssetInput }
556
+
557
+ export { PersistMediaBundleAssociationInput }
558
+
559
+ export { persistMediaBundleInspection }
560
+
561
+ export { PersistMediaBundleInspectionOptions }
562
+
563
+ export { PersistMediaBundleInspectionResult }
564
+
565
+ export { PersistMediaBundleMetadataArtifactInput }
566
+
567
+ /**
568
+ * Render status for the composition
569
+ */
570
+ export declare type RenderStatus = 'draft' | 'rendering' | 'ready' | 'failed';
571
+
572
+ /**
573
+ * Scene for virtual production compositing
574
+ *
575
+ * Supports 360° panoramas, standard images, and video backgrounds
576
+ * with viewpoint extraction, lighting analysis, and character placement.
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * import { Scene } from '@happyvertical/smrt-video';
581
+ *
582
+ * const scene = new Scene({
583
+ * name: 'Town Hall Exterior',
584
+ * sourceAssetId: 'asset-townhall-pano',
585
+ * sourceType: 'panorama_360',
586
+ * projection: 'equirectangular',
587
+ * });
588
+ * await scene.save();
589
+ * ```
590
+ */
591
+ export declare class Scene extends SmrtObject {
592
+ tenantId: string | null;
593
+ /** Human-readable name */
594
+ name: string;
595
+ /** Description */
596
+ description: string | null;
597
+ /** Source media asset ID */
598
+ sourceAssetId: string | null;
599
+ /** Type of source media */
600
+ sourceType: SceneSourceType;
601
+ /** Projection type for panoramas */
602
+ projection: SceneProjection | null;
603
+ /** Extracted camera angles from 360° panoramas */
604
+ viewpoints: SceneViewpoint[];
605
+ /** Lighting analysis for IC-Light matching */
606
+ lightingProfile: LightingProfile | null;
607
+ /** Location metadata */
608
+ location: {
609
+ name: string;
610
+ coordinates?: {
611
+ lat: number;
612
+ lng: number;
613
+ };
614
+ } | null;
615
+ /** Anchor points for character placement */
616
+ anchorPoints: AnchorPoint[];
617
+ /** Scene status */
618
+ status: SceneStatus;
619
+ constructor(options?: SceneOptions);
620
+ private getSceneAssetCollection;
621
+ private getLegacyFieldAssetIds;
622
+ private setLegacyFieldAssetId;
623
+ private clearLegacyFieldAssetId;
624
+ getAssets(role?: SceneAssetRole): Promise<Asset[]>;
625
+ getAssetByRole(role: SceneAssetRole): Promise<Asset | null>;
626
+ addAsset(asset: Asset, role?: SceneAssetRole, sortOrder?: number): Promise<void>;
627
+ removeAsset(assetId: string, role?: SceneAssetRole): Promise<void>;
628
+ /** Check if this is a 360° panorama */
629
+ get isPanorama(): boolean;
630
+ /** Check if the scene has viewpoints extracted */
631
+ get hasViewpoints(): boolean;
632
+ /** Check if the scene is ready for compositing */
633
+ get isReady(): boolean;
634
+ }
635
+
636
+ export declare class SceneAsset extends Asset {
637
+ sceneId: string | null;
638
+ role: SceneAssetRole;
639
+ constructor(options?: SceneAssetOptions);
640
+ }
641
+
642
+ export declare interface SceneAssetOptions extends AssetOptions {
643
+ /** Scene this asset belongs to */
644
+ sceneId?: string | null;
645
+ /** Role of this asset for the scene */
646
+ role?: SceneAssetRole;
647
+ }
648
+
649
+ /** Roles a scene asset can play */
650
+ export declare type SceneAssetRole = 'source' | 'viewpoint-extract' | 'env-map';
651
+
652
+ /**
653
+ * Scene creation options
654
+ */
655
+ export declare interface SceneOptions extends SmrtObjectOptions {
656
+ /** Human-readable name */
657
+ name?: string;
658
+ /** Description */
659
+ description?: string | null;
660
+ /** Source media asset ID */
661
+ sourceAssetId?: string | null;
662
+ /** Type of source media */
663
+ sourceType?: SceneSourceType;
664
+ /** Projection type for panoramas */
665
+ projection?: SceneProjection | null;
666
+ /** Extracted camera angles from 360° panoramas */
667
+ viewpoints?: SceneViewpoint[];
668
+ /** Lighting analysis for IC-Light matching */
669
+ lightingProfile?: LightingProfile | null;
670
+ /** Location metadata */
671
+ location?: {
672
+ name: string;
673
+ coordinates?: {
674
+ lat: number;
675
+ lng: number;
676
+ };
677
+ } | null;
678
+ /** Anchor points for character placement */
679
+ anchorPoints?: AnchorPoint[];
680
+ /** Scene status */
681
+ status?: SceneStatus;
682
+ /** Tenant ID for multi-tenant isolation */
683
+ tenantId?: string | null;
684
+ }
685
+
686
+ export declare class SceneOwnedAsset extends SmrtObject {
687
+ tenantId: string | null;
688
+ sceneId: string;
689
+ assetId: string;
690
+ role: SceneAssetRole;
691
+ sortOrder: number;
692
+ constructor(options?: SceneOwnedAssetOptions);
693
+ }
694
+
695
+ export declare class SceneOwnedAssetCollection extends SmrtJunction<SceneOwnedAsset> {
696
+ static readonly _itemClass: typeof SceneOwnedAsset;
697
+ protected leftField: string;
698
+ protected rightField: string;
699
+ }
700
+
701
+ export declare interface SceneOwnedAssetOptions extends SmrtObjectOptions {
702
+ sceneId?: string;
703
+ assetId?: string;
704
+ role?: SceneAssetRole;
705
+ sortOrder?: number;
706
+ tenantId?: string | null;
707
+ }
708
+
709
+ /**
710
+ * Scene projection type
711
+ */
712
+ export declare type SceneProjection = 'equirectangular' | 'cubemap';
713
+
714
+ /**
715
+ * Scene source type
716
+ */
717
+ export declare type SceneSourceType = 'image' | 'video' | 'panorama_360' | 'panorama_180';
718
+
719
+ /**
720
+ * Scene status
721
+ */
722
+ export declare type SceneStatus = 'pending' | 'processing' | 'ready' | 'failed';
723
+
724
+ /**
725
+ * Viewpoint extracted from 360° scene
726
+ */
727
+ export declare interface SceneViewpoint {
728
+ /** Viewpoint identifier */
729
+ id: string;
730
+ /** Human-readable name */
731
+ name: string;
732
+ /** Horizontal rotation (-180 to 180°) */
733
+ pan: number;
734
+ /** Vertical rotation (-90 to 90°) */
735
+ tilt: number;
736
+ /** Field of view (60-120°) */
737
+ fov: number;
738
+ /** Generated rectilinear image asset ID */
739
+ extractedAssetId?: string;
740
+ /** Viewpoint-specific lighting profile */
741
+ lightingProfile?: LightingProfile;
742
+ }
743
+
744
+ export { SmrtMediaBundlePersistenceAdapter }
745
+
746
+ /**
747
+ * Transition type to the next sequence
748
+ */
749
+ export declare type TransitionType = 'none' | 'fade' | 'slide' | 'wipe';
750
+
751
+ /**
752
+ * Publishable video composition
753
+ *
754
+ * VideoComposition is the top-level container for a rendered video.
755
+ * It defines the render spec and contains ordered VideoSequences.
756
+ *
757
+ * @example
758
+ * ```typescript
759
+ * import { VideoComposition } from '@happyvertical/smrt-video';
760
+ *
761
+ * const composition = new VideoComposition({
762
+ * title: 'Evening News - January 25, 2026',
763
+ * fps: 30,
764
+ * width: 1920,
765
+ * height: 1080,
766
+ * });
767
+ * await composition.save();
768
+ * ```
769
+ */
770
+ export declare class VideoComposition extends Content {
771
+ /** Frames per second — everything downstream is in frames */
772
+ fps: number;
773
+ /** Render width in pixels */
774
+ width: number;
775
+ /** Render height in pixels */
776
+ height: number;
777
+ /** Computed total: sum of sequences minus transition overlaps */
778
+ durationInFrames: number;
779
+ /** Render status */
780
+ renderStatus: RenderStatus;
781
+ /** Render progress (0-100) */
782
+ renderProgress: number;
783
+ constructor(options?: VideoCompositionOptions);
784
+ /** Duration in seconds */
785
+ get durationInSeconds(): number;
786
+ /** Check if the composition is ready for publishing */
787
+ get isReady(): boolean;
788
+ /** Check if the composition is currently rendering */
789
+ get isRendering(): boolean;
790
+ getAssets(relationship?: string): Promise<Asset[]>;
791
+ getAssets(role?: VideoCompositionAssetRole): Promise<Asset[]>;
792
+ getAssetByRole(role: VideoCompositionAssetRole): Promise<Asset | null>;
793
+ }
794
+
795
+ export declare class VideoCompositionAsset extends Asset {
796
+ videoCompositionId: string | null;
797
+ role: VideoCompositionAssetRole;
798
+ constructor(options?: VideoCompositionAssetOptions);
799
+ }
800
+
801
+ export declare interface VideoCompositionAssetOptions extends AssetOptions {
802
+ /** VideoComposition this asset belongs to */
803
+ videoCompositionId?: string | null;
804
+ /** Role of this asset for the composition */
805
+ role?: VideoCompositionAssetRole;
806
+ }
807
+
808
+ /** Roles a video composition asset can play */
809
+ export declare type VideoCompositionAssetRole = 'video' | 'audio' | 'thumbnail';
810
+
811
+ export declare class VideoCompositionCollection extends SmrtCollection<VideoComposition> {
812
+ static readonly _itemClass: typeof VideoComposition;
813
+ /** Find compositions by render status */
814
+ findByRenderStatus(renderStatus: RenderStatus): Promise<VideoComposition[]>;
815
+ /** Find compositions that are ready for publishing */
816
+ findReady(): Promise<VideoComposition[]>;
817
+ }
818
+
819
+ /**
820
+ * VideoComposition creation options
821
+ */
822
+ export declare interface VideoCompositionOptions extends ContentOptions {
823
+ /** Frames per second (e.g., 30) — everything downstream is in frames */
824
+ fps?: number;
825
+ /** Render width in pixels */
826
+ width?: number;
827
+ /** Render height in pixels */
828
+ height?: number;
829
+ /** Computed total: sum of sequences minus transition overlaps */
830
+ durationInFrames?: number;
831
+ /** Render status */
832
+ renderStatus?: RenderStatus;
833
+ /** Render progress (0-100) */
834
+ renderProgress?: number;
835
+ }
836
+
837
+ /**
838
+ * Video metadata
839
+ */
840
+ export declare interface VideoMetadata {
841
+ /** Actual duration in seconds */
842
+ duration?: number;
843
+ /** Video resolution (e.g., "1920x1080") */
844
+ resolution?: string;
845
+ /** Aspect ratio (e.g., "16:9", "9:16") */
846
+ aspectRatio?: string;
847
+ /** Video codec (e.g., "h264", "h265") */
848
+ codec?: string;
849
+ /** Frames per second */
850
+ fps?: number;
851
+ /** File size in bytes */
852
+ fileSize?: number;
853
+ /** Word timing data from TTS for lip-sync */
854
+ wordTimings?: WordTiming[];
855
+ /** ComfyUI prompt ID for tracking */
856
+ comfyPromptId?: string;
857
+ }
858
+
859
+ /**
860
+ * Thematic section of a video composition
861
+ *
862
+ * VideoSequence groups VideoShots into a logical section. It can belong
863
+ * to a VideoComposition or exist standalone (e.g., during long-video generation).
864
+ *
865
+ * @example
866
+ * ```typescript
867
+ * import { VideoSequence } from '@happyvertical/smrt-video';
868
+ *
869
+ * const sequence = new VideoSequence({
870
+ * title: 'Top Story',
871
+ * position: 0,
872
+ * transitionType: 'fade',
873
+ * transitionDurationFrames: 15,
874
+ * });
875
+ * await sequence.save();
876
+ * ```
877
+ */
878
+ export declare class VideoSequence extends Content {
879
+ /** Composition this sequence belongs to */
880
+ compositionId: string | null;
881
+ /** Order within composition */
882
+ position: number;
883
+ /** Computed duration: sum of shot frames */
884
+ durationInFrames: number;
885
+ /** Transition type to the next sequence */
886
+ transitionType: TransitionType;
887
+ /** Overlap frames with next sequence for transition */
888
+ transitionDurationFrames: number;
889
+ constructor(options?: VideoSequenceOptions);
890
+ getAssets(relationship?: string): Promise<Asset[]>;
891
+ getAssets(role?: VideoSequenceAssetRole): Promise<Asset[]>;
892
+ getAssetByRole(role: VideoSequenceAssetRole): Promise<Asset | null>;
893
+ }
894
+
895
+ export declare class VideoSequenceAsset extends Asset {
896
+ videoSequenceId: string | null;
897
+ role: VideoSequenceAssetRole;
898
+ constructor(options?: VideoSequenceAssetOptions);
899
+ }
900
+
901
+ export declare interface VideoSequenceAssetOptions extends AssetOptions {
902
+ /** VideoSequence this asset belongs to */
903
+ videoSequenceId?: string | null;
904
+ /** Role of this asset for the sequence */
905
+ role?: VideoSequenceAssetRole;
906
+ }
907
+
908
+ /** Roles a video sequence asset can play */
909
+ export declare type VideoSequenceAssetRole = 'video' | 'audio' | 'thumbnail';
910
+
911
+ export declare class VideoSequenceCollection extends SmrtCollection<VideoSequence> {
912
+ static readonly _itemClass: typeof VideoSequence;
913
+ /** Find sequences belonging to a composition, ordered by position */
914
+ findByComposition(compositionId: string): Promise<VideoSequence[]>;
915
+ /** Find standalone sequences (not in any composition) */
916
+ findStandalone(): Promise<VideoSequence[]>;
917
+ }
918
+
919
+ /**
920
+ * VideoSequence creation options
921
+ */
922
+ export declare interface VideoSequenceOptions extends ContentOptions {
923
+ /** Composition this sequence belongs to (nullable — can exist standalone) */
924
+ compositionId?: string | null;
925
+ /** Order within composition */
926
+ position?: number;
927
+ /** Computed duration: sum of shot frames */
928
+ durationInFrames?: number;
929
+ /** Transition type to the next sequence */
930
+ transitionType?: TransitionType;
931
+ /** Overlap frames with next sequence for transition */
932
+ transitionDurationFrames?: number;
933
+ }
934
+
935
+ /**
936
+ * Atomic video generation unit
937
+ *
938
+ * VideoShot represents a single pipeline run producing one video clip.
939
+ * It can belong to a VideoSequence (for multi-segment long videos) or
940
+ * exist standalone. Characters are linked via the VideoShotCharacter join model.
941
+ *
942
+ * @example
943
+ * ```typescript
944
+ * import { VideoShot } from '@happyvertical/smrt-video';
945
+ *
946
+ * const shot = new VideoShot({
947
+ * scriptText: 'Welcome to the evening news.',
948
+ * targetDuration: 30,
949
+ * title: 'Evening News - Opening',
950
+ * });
951
+ * await shot.save();
952
+ * ```
953
+ */
954
+ declare class VideoShot extends Content {
955
+ /** Sequence this shot belongs to */
956
+ sequenceId: string | null;
957
+ /** Scene for this shot */
958
+ sceneId: string | null;
959
+ /** Order within sequence */
960
+ position: number;
961
+ /** Actual frame count of generated clip */
962
+ durationInFrames: number;
963
+ /** Frames to skip at start (overlap handling) */
964
+ trimBeforeFrames: number;
965
+ /** Frames to skip at end */
966
+ trimAfterFrames: number;
967
+ /** Script text to be spoken */
968
+ scriptText: string;
969
+ /** Word count in the script */
970
+ scriptWordCount: number;
971
+ /** Target duration in seconds */
972
+ targetDuration: number;
973
+ /** Video generation status */
974
+ shotStatus: VideoShotStatus;
975
+ /** Generation progress (0-100) */
976
+ progress: number;
977
+ /** Error message if status is 'failed' */
978
+ errorMessage: string | null;
979
+ /** Detailed status message for progress tracking */
980
+ statusMessage: string | null;
981
+ /** Video metadata (duration, resolution, etc.) */
982
+ videoMetadata: VideoMetadata;
983
+ constructor(options?: VideoShotOptions);
984
+ /** Estimate speech duration based on word count (2.7 words/sec) */
985
+ get estimatedDuration(): number;
986
+ /** Check if the script length matches target duration (+/- 15%) */
987
+ get isScriptLengthValid(): boolean;
988
+ /** Get the recommended word count for target duration */
989
+ get recommendedWordCount(): {
990
+ min: number;
991
+ max: number;
992
+ target: number;
993
+ };
994
+ /** Effective frame count after trimming */
995
+ get effectiveFrames(): number;
996
+ /** Check if video generation is in progress */
997
+ get isGenerating(): boolean;
998
+ /** Check if video is ready for publishing */
999
+ get isReady(): boolean;
1000
+ getAssets(relationship?: string): Promise<Asset[]>;
1001
+ getAssets(role?: VideoShotAssetRole): Promise<Asset[]>;
1002
+ getAssetByRole(role: VideoShotAssetRole): Promise<Asset | null>;
1003
+ /** Update script text and recalculate word count */
1004
+ setScript(text: string): void;
1005
+ }
1006
+ export { VideoShot as VideoContent }
1007
+ export { VideoShot }
1008
+
1009
+ export declare class VideoShotAsset extends Asset {
1010
+ videoShotId: string | null;
1011
+ role: VideoShotAssetRole;
1012
+ constructor(options?: VideoShotAssetOptions);
1013
+ }
1014
+
1015
+ export declare interface VideoShotAssetOptions extends AssetOptions {
1016
+ /** VideoShot this asset belongs to */
1017
+ videoShotId?: string | null;
1018
+ /** Role of this asset for the shot */
1019
+ role?: VideoShotAssetRole;
1020
+ }
1021
+
1022
+ /** Roles a video shot asset can play */
1023
+ export declare type VideoShotAssetRole = 'video' | 'audio' | 'thumbnail';
1024
+
1025
+ /**
1026
+ * Join model linking a VideoShot to a Character
1027
+ *
1028
+ * @example
1029
+ * ```typescript
1030
+ * import { VideoShotCharacter } from '@happyvertical/smrt-video';
1031
+ *
1032
+ * const link = new VideoShotCharacter({
1033
+ * videoShotId: 'shot-123',
1034
+ * characterId: 'char-456',
1035
+ * role: 'primary',
1036
+ * position: 0,
1037
+ * });
1038
+ * await link.save();
1039
+ * ```
1040
+ */
1041
+ export declare class VideoShotCharacter extends SmrtObject {
1042
+ tenantId: string | null;
1043
+ /** Video shot ID */
1044
+ videoShotId: string;
1045
+ /** Character ID */
1046
+ characterId: string;
1047
+ /** Role of the character in this shot */
1048
+ role: VideoShotCharacterRole;
1049
+ /** Order/layer position within the shot */
1050
+ position: number;
1051
+ constructor(options: VideoShotCharacterOptions);
1052
+ }
1053
+
1054
+ export declare class VideoShotCharacterCollection extends SmrtCollection<VideoShotCharacter> {
1055
+ static readonly _itemClass: typeof VideoShotCharacter;
1056
+ /** Find all character links for a shot, ordered by position */
1057
+ findByShot(videoShotId: string): Promise<VideoShotCharacter[]>;
1058
+ /** Find all shot links for a character */
1059
+ findByCharacter(characterId: string): Promise<VideoShotCharacter[]>;
1060
+ }
1061
+
1062
+ /**
1063
+ * VideoShotCharacter creation options
1064
+ */
1065
+ export declare interface VideoShotCharacterOptions extends SmrtObjectOptions {
1066
+ /** Video shot ID */
1067
+ videoShotId: string;
1068
+ /** Character ID */
1069
+ characterId: string;
1070
+ /** Role of the character in this shot */
1071
+ role?: VideoShotCharacterRole;
1072
+ /** Order/layer position within the shot */
1073
+ position?: number;
1074
+ /** Tenant ID for multi-tenant isolation */
1075
+ tenantId?: string | null;
1076
+ }
1077
+
1078
+ /**
1079
+ * Character role within a shot
1080
+ */
1081
+ export declare type VideoShotCharacterRole = 'primary' | 'secondary' | 'background';
1082
+
1083
+ export declare class VideoShotCollection extends SmrtCollection<VideoShot> {
1084
+ static readonly _itemClass: typeof VideoShot;
1085
+ /** Find shots belonging to a specific sequence, ordered by position */
1086
+ findBySequence(sequenceId: string): Promise<VideoShot[]>;
1087
+ /** Find shots by status */
1088
+ findByStatus(shotStatus: VideoShotStatus): Promise<VideoShot[]>;
1089
+ /** Find standalone shots (not in any sequence) */
1090
+ findStandalone(): Promise<VideoShot[]>;
1091
+ }
1092
+
1093
+ /**
1094
+ * Video shot creation options
1095
+ */
1096
+ declare interface VideoShotOptions extends ContentOptions {
1097
+ /** Sequence this shot belongs to (nullable — shots can exist standalone) */
1098
+ sequenceId?: string | null;
1099
+ /** Scene for this shot (nullable) */
1100
+ sceneId?: string | null;
1101
+ /** Order within sequence */
1102
+ position?: number;
1103
+ /** Actual frame count of generated clip */
1104
+ durationInFrames?: number;
1105
+ /** Frames to skip at start (overlap handling) */
1106
+ trimBeforeFrames?: number;
1107
+ /** Frames to skip at end */
1108
+ trimAfterFrames?: number;
1109
+ /** Script text to be spoken */
1110
+ scriptText?: string;
1111
+ /** Word count in the script */
1112
+ scriptWordCount?: number;
1113
+ /** Target duration in seconds */
1114
+ targetDuration?: number;
1115
+ /** Video generation status */
1116
+ shotStatus?: VideoShotStatus;
1117
+ /** Generation progress (0-100) */
1118
+ progress?: number;
1119
+ /** Error message if status is 'failed' */
1120
+ errorMessage?: string | null;
1121
+ /** Detailed status message for progress tracking */
1122
+ statusMessage?: string | null;
1123
+ /** Video metadata */
1124
+ videoMetadata?: VideoMetadata;
1125
+ }
1126
+ export { VideoShotOptions as VideoContentOptions }
1127
+ export { VideoShotOptions }
1128
+
1129
+ /**
1130
+ * Video shot status
1131
+ */
1132
+ declare type VideoShotStatus = 'draft' | 'queued' | 'processing' | 'ready' | 'failed' | 'published';
1133
+ export { VideoShotStatus as VideoContentStatus }
1134
+ export { VideoShotStatus }
1135
+
1136
+ /**
1137
+ * ComfyUI workflow template for video generation
1138
+ *
1139
+ * VideoWorkflow stores ComfyUI workflow definitions with node mappings
1140
+ * for dynamic parameter injection. This allows the Histrio agent to
1141
+ * inject anchor images, audio, and other inputs at runtime.
1142
+ *
1143
+ * @example
1144
+ * ```typescript
1145
+ * import { VideoWorkflow } from '@happyvertical/smrt-video';
1146
+ *
1147
+ * const workflow = new VideoWorkflow({
1148
+ * name: 'Wan 2.6 + EchoMimic',
1149
+ * description: 'Full broadcast generation with lip-sync',
1150
+ * workflowType: 'broadcast',
1151
+ * workflowJson: comfyuiWorkflowJson,
1152
+ * nodeMapping: {
1153
+ * seedImage: '1',
1154
+ * audioFile: '5',
1155
+ * outputVideo: '12',
1156
+ * },
1157
+ * estimatedTime: 600, // 10 minutes
1158
+ * requiredModels: ['wan_2.6_t2v_14b_fp8', 'echomimic_v2'],
1159
+ * });
1160
+ * await workflow.save();
1161
+ * ```
1162
+ */
1163
+ export declare class VideoWorkflow extends SmrtObject {
1164
+ /**
1165
+ * Tenant ID for multi-tenant isolation
1166
+ */
1167
+ tenantId: string | null;
1168
+ /**
1169
+ * Human-readable name for the workflow
1170
+ */
1171
+ name: string;
1172
+ /**
1173
+ * Description of what this workflow does
1174
+ */
1175
+ description: string | null;
1176
+ /**
1177
+ * Workflow type classification
1178
+ * - prebake: Pre-generate base motion from seed image
1179
+ * - broadcast: Full video generation pipeline
1180
+ * - lipsync: Lip-sync only (requires base video + audio)
1181
+ * - postprod: Post-production overlays and effects
1182
+ * - custom: User-defined workflow
1183
+ */
1184
+ workflowType: WorkflowType;
1185
+ /**
1186
+ * ComfyUI API format JSON
1187
+ * This is the workflow definition that will be sent to ComfyUI
1188
+ */
1189
+ workflowJson: object | null;
1190
+ /**
1191
+ * Node ID mappings for dynamic parameter injection
1192
+ * Maps semantic names to ComfyUI node IDs
1193
+ */
1194
+ nodeMapping: NodeMapping;
1195
+ /**
1196
+ * Estimated processing time in seconds
1197
+ * Used for progress estimation
1198
+ */
1199
+ estimatedTime: number;
1200
+ /**
1201
+ * Whether this workflow is active/usable
1202
+ */
1203
+ isActive: boolean;
1204
+ /**
1205
+ * ComfyUI models required by this workflow
1206
+ * Used for validation before queuing
1207
+ */
1208
+ requiredModels: string[];
1209
+ constructor(options?: VideoWorkflowOptions);
1210
+ /**
1211
+ * Check if the workflow has all required node mappings
1212
+ */
1213
+ get hasRequiredMappings(): boolean;
1214
+ /**
1215
+ * Get a copy of the workflow JSON with injected parameters
1216
+ *
1217
+ * Parameter injection follows ComfyUI node structure conventions:
1218
+ * - seedImage, audioFile, baseVideo → node.inputs.image (file path)
1219
+ * - prompt → node.inputs.text (string)
1220
+ * - Other parameters → node.inputs[paramKey]
1221
+ *
1222
+ * @param params - Key-value pairs of parameters to inject
1223
+ * @returns Modified workflow JSON or null if no workflowJson set
1224
+ */
1225
+ injectParameters(params: Record<string, any>): object | null;
1226
+ }
1227
+
1228
+ /**
1229
+ * Video workflow creation options
1230
+ */
1231
+ export declare interface VideoWorkflowOptions extends SmrtObjectOptions {
1232
+ /**
1233
+ * Human-readable name for the workflow
1234
+ */
1235
+ name?: string;
1236
+ /**
1237
+ * Description of what this workflow does
1238
+ */
1239
+ description?: string | null;
1240
+ /**
1241
+ * Workflow type classification
1242
+ * @default 'custom'
1243
+ */
1244
+ workflowType?: WorkflowType;
1245
+ /**
1246
+ * ComfyUI API format JSON
1247
+ */
1248
+ workflowJson?: object | null;
1249
+ /**
1250
+ * Node ID mappings for dynamic parameter injection
1251
+ */
1252
+ nodeMapping?: NodeMapping;
1253
+ /**
1254
+ * Estimated processing time in seconds
1255
+ */
1256
+ estimatedTime?: number;
1257
+ /**
1258
+ * Whether this workflow is active/usable
1259
+ * @default true
1260
+ */
1261
+ isActive?: boolean;
1262
+ /**
1263
+ * ComfyUI models required by this workflow
1264
+ */
1265
+ requiredModels?: string[];
1266
+ /**
1267
+ * Tenant ID for multi-tenant isolation
1268
+ */
1269
+ tenantId?: string | null;
1270
+ }
1271
+
1272
+ /**
1273
+ * Workflow type classification
1274
+ */
1275
+ export declare type WorkflowType = 'prebake' | 'broadcast' | 'lipsync' | 'postprod' | 'custom';
1276
+
1277
+ export { }