@streamoji/aitwin 0.7.5 → 0.7.7

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/dist/index.d.ts CHANGED
@@ -15,6 +15,26 @@ export declare type AiTwinCaptionsOptions = {
15
15
  color?: string;
16
16
  };
17
17
 
18
+ export declare type AiTwinGestureCatalog = {
19
+ success: boolean;
20
+ fullBody: boolean;
21
+ kind?: string;
22
+ poses: string[];
23
+ poseDetails?: Array<{
24
+ id: string;
25
+ label: string;
26
+ description?: string;
27
+ keywords?: string[];
28
+ category?: string;
29
+ speechMapped?: boolean;
30
+ cdnPath?: string;
31
+ }>;
32
+ encrypted: boolean;
33
+ pathTemplate: string;
34
+ cropMetaPath: string;
35
+ notes?: string;
36
+ };
37
+
18
38
  export declare type AiTwinHandle = {
19
39
  speakText: (text: string, options?: AvatarTtsSpeakOptions) => Promise<void>;
20
40
  /**
@@ -40,6 +60,8 @@ export declare type AiTwinHandle = {
40
60
  clearEmotionPreview: () => void;
41
61
  isReady: () => boolean;
42
62
  getStatus: () => AvatarTtsLipsyncStatus;
63
+ /** Current utterance word queue (includes `gesture` when fullBody TTS mapped poses). */
64
+ getWordQueue: () => WordQueueItem[];
43
65
  /** Connect mic + WebSocket voice session over `/ws/voice`. */
44
66
  connect: (options?: VoiceConnectOptions) => Promise<void>;
45
67
  /** Disconnect voice session. */
@@ -146,6 +168,18 @@ export declare type AiTwinProps = {
146
168
  * Default: 500.
147
169
  */
148
170
  idleHandoffHoldMs?: number;
171
+ /**
172
+ * When true, skip loading/playing the cloud head idle MP4 (still sil only
173
+ * between speech). Demo pages can overlay a custom full-body idle instead.
174
+ * Default: false.
175
+ */
176
+ disableIdleVideo?: boolean;
177
+ /**
178
+ * Full-body (waist-up) twin: disable head idle and overlay encrypted CDN
179
+ * body idle + gesture videos under `custom-faces/{faceId}/ges/` as `G_00N.bin`.
180
+ * Create with `createAiTwinFace({ fullBody: true, … })`.
181
+ */
182
+ fullBody?: boolean;
149
183
  /**
150
184
  * Pixi only: cap WebGL MAX_TEXTURE_SIZE (e.g. 4096) to preview mobile-GPU
151
185
  * atlas handling. Omit to use the device limit.
@@ -251,6 +285,11 @@ export declare type AiTwinWidgetProps = {
251
285
  * Default: false (inline in the mount target).
252
286
  */
253
287
  float?: boolean;
288
+ /**
289
+ * Full-body twin: body idle + gesture overlays from CDN.
290
+ * Create via `createAiTwinFace({ fullBody: true })`.
291
+ */
292
+ fullBody?: boolean;
254
293
  /**
255
294
  * Brain id for `speakWithReply` (Text mode) and `/ws/voice`.
256
295
  * When omitted, uses getAiTwin `brainId` if available.
@@ -296,6 +335,8 @@ export declare type AvatarTtsLipsyncController = {
296
335
  */
297
336
  speakWithReply: (message: string, options?: SpeakWithReplyOptions) => Promise<SpeakWithReplyResult>;
298
337
  stop: () => void;
338
+ /** Let a `delayPlayback` request become audible. */
339
+ releasePlaybackHold: () => void;
299
340
  getVisemeQueue: () => VisemeQueueItem[];
300
341
  getWordQueue: () => WordQueueItem[];
301
342
  /** Full utterance viseme queue (all SSE chunks, cumulative vtimes) for debug. */
@@ -320,6 +361,11 @@ export declare type AvatarTtsLipsyncController = {
320
361
 
321
362
  declare type AvatarTtsLipsyncControllerOptions = {
322
363
  onLipsyncDebug?: (snapshot: RealtimeLipsyncDebugSnapshot) => void;
364
+ /**
365
+ * When true, `/avatar_ttsWithPoses` uses the full-body PixVerse pose vocab
366
+ * and stamps `words[].gesture` with CDN codes (G_002, G_004, …).
367
+ */
368
+ fullBody?: boolean;
323
369
  };
324
370
 
325
371
  export declare type AvatarTtsLipsyncStatus = "idle" | "loading" | "speaking" | "done" | "error";
@@ -335,6 +381,16 @@ export declare type AvatarTtsSpeakOptions = {
335
381
  * Sent as `language` on `/avatar_ttsWithPoses`.
336
382
  */
337
383
  language?: TtsLanguage;
384
+ /**
385
+ * Override controller `fullBody` for this request. When true, backend maps
386
+ * speech to PixVerse gesture codes (G_002, …) on `words[].gesture`.
387
+ */
388
+ fullBody?: boolean;
389
+ /**
390
+ * Buffer audio and visemes, but do not start playback until
391
+ * `releasePlaybackHold()`. Used so full-body speech starts on an idle boundary.
392
+ */
393
+ delayPlayback?: boolean;
338
394
  };
339
395
 
340
396
  /** Pair transitions for playback, including sil→first and last→sil bookends. */
@@ -355,6 +411,23 @@ export declare function compactSkippableVisemes(series: VisemeQueueItem[]): Vise
355
411
 
356
412
  export declare const CONSONANT_SKIP_GROUP: Set<string>;
357
413
 
414
+ /** Upload a portrait and enqueue the twin-face pipeline (poll with getAiTwinFaceStatus). */
415
+ export declare function createAiTwinFace(options: CreateAiTwinFaceOptions): Promise<TwinFaceJobResponse>;
416
+
417
+ export declare type CreateAiTwinFaceOptions = {
418
+ /** Bearer token (Firebase ID token or `client_…` JWT). */
419
+ authToken: string;
420
+ image: Blob | File;
421
+ name?: string;
422
+ /**
423
+ * Create a full-body (waist-up) twin: NanoBanana front-facing correction,
424
+ * then PixVerse idle + gesture videos (encrypted on CDN like idle.bin).
425
+ */
426
+ fullBody?: boolean;
427
+ /** Default: package `DEFAULT_API_BASE` (https://ai.aitwin.me). */
428
+ apiBase?: string;
429
+ };
430
+
358
431
  export declare function createAvatarTtsLipsyncController(onStatus: (status: AvatarTtsLipsyncStatus) => void, apiBase?: string, options?: AvatarTtsLipsyncControllerOptions): AvatarTtsLipsyncController;
359
432
 
360
433
  export declare function createRealtimeVoiceLipsyncController(onStatus: (status: AvatarTtsLipsyncStatus) => void, initialOptions?: RealtimeVoiceOptions): RealtimeVoiceLipsyncController;
@@ -450,12 +523,43 @@ declare type FrameRenderTransitionMeta = {
450
523
  omittedByGap: number;
451
524
  };
452
525
 
526
+ /** Default PixVerse full-body pose catalog (matches pipeline). */
527
+ export declare const FULLBODY_GESTURE_POSES: readonly ["open_palm", "emphasis", "thumbs_up", "friendly_wave", "point_camera"];
528
+
529
+ export declare type FullBodyCropMeta = {
530
+ y_end: number;
531
+ silHeight: number;
532
+ silWidth: number;
533
+ seamLockPx?: number;
534
+ poses?: string[];
535
+ encrypted?: boolean;
536
+ videoBin?: string;
537
+ };
538
+
539
+ export declare type FullBodyGesturePose = (typeof FULLBODY_GESTURE_POSES)[number];
540
+
541
+ export declare function gesturesBaseForFace(faceId: string, cdnBase?: string): string;
542
+
543
+ export declare function getAiTwinFaceStatus(avatarId: string, options: {
544
+ authToken: string;
545
+ apiBase?: string;
546
+ }): Promise<TwinFaceJobResponse>;
547
+
548
+ /** Server catalog for full-body PixVerse poses (idle + gestures). */
549
+ export declare function getAiTwinGestureCatalog(apiBase?: string): Promise<AiTwinGestureCatalog>;
550
+
453
551
  /** Public CDN original portrait for custom-faces/{faceId}/ (same id as pipeline avatarId). */
454
552
  export declare function getAiTwinSourceUrl(faceId: string, cdnBase?: string, extension?: string): string;
455
553
 
456
554
  /** Public CDN thumbnail for custom-faces/{faceId}/ (same id as pipeline avatarId). */
457
555
  export declare function getAiTwinThumbnailUrl(faceId: string, cdnBase?: string): string;
458
556
 
557
+ export declare function getFullBodyCropMetaUrl(gesturesBase: string): string;
558
+
559
+ export declare function getFullBodyGestureBinUrl(gesturesBase: string, pose: string): string;
560
+
561
+ export declare function isFullBodyGesturePose(id: string | null | undefined): id is FullBodyGesturePose;
562
+
459
563
  export declare function isTtsLanguageCode(raw: string): raw is TtsLanguage;
460
564
 
461
565
  export declare function isTtsLanguageSupported(engineId: TtsEngineId, language: string): boolean;
@@ -467,6 +571,12 @@ export declare function listSkippedVisemes(queue: VisemeQueueItem[]): string[];
467
571
 
468
572
  export declare const MIC_SAMPLE_RATE = 16000;
469
573
 
574
+ /**
575
+ * Map a TTS `words[].gesture` token to a pose id.
576
+ * Accepts pose names (`open_palm`) and CDN codes (`G_002`).
577
+ */
578
+ export declare function normalizeFullBodyGesturePose(id: string | null | undefined): FullBodyGesturePose | null;
579
+
470
580
  /** Google TTS streams Oculus viseme symbols; normalize casing and unknown ids. */
471
581
  export declare function normalizeOculusViseme(symbol: string | null | undefined): string;
472
582
 
@@ -924,6 +1034,33 @@ declare type TwinBrainFields = {
924
1034
  brainUrl?: string | null;
925
1035
  };
926
1036
 
1037
+ export declare type TwinFaceJobResponse = {
1038
+ avatarId: string;
1039
+ twinName: string;
1040
+ status: TwinFaceJobStatus;
1041
+ message: string;
1042
+ success: boolean;
1043
+ createdAt?: string;
1044
+ updatedAt?: string;
1045
+ error?: string;
1046
+ deliverables?: string[];
1047
+ twinPath?: string;
1048
+ r2PublicBase?: string;
1049
+ thumbnailUrl?: string;
1050
+ sourceUrl?: string;
1051
+ gender?: string;
1052
+ genderConfidence?: number;
1053
+ genderError?: string;
1054
+ /** When true, pipeline runs waist-up NanoBanana + PixVerse gestures. */
1055
+ fullBody?: boolean;
1056
+ gesturesReady?: boolean;
1057
+ gestures?: string[];
1058
+ gesturesBase?: string;
1059
+ gesturesError?: string;
1060
+ };
1061
+
1062
+ export declare type TwinFaceJobStatus = "queued" | "running" | "succeeded" | "failed";
1063
+
927
1064
  export declare const VISEME_IDS: readonly ["aa", "E", "I", "O", "U", "PP", "FF", "DD", "SS", "TH", "CH", "RR", "kk", "nn"];
928
1065
 
929
1066
  /** Minimum gap (ms) between consecutive vtimes to keep a skippable viseme. */
@@ -962,6 +1099,20 @@ export declare type VoiceConnectOptions = {
962
1099
  * Sent as `language` on `/ws/voice` and redirected `/avatar_ttsWithPoses` calls.
963
1100
  */
964
1101
  language?: TtsLanguage;
1102
+ /**
1103
+ * When true, redirected `/avatar_ttsWithPoses` uses full-body PixVerse pose vocab.
1104
+ */
1105
+ fullBody?: boolean;
1106
+ /**
1107
+ * Full-body only: resolve when the current body-idle clip ends so speech
1108
+ * does not start mid-loop. Null when the body layer is not mounted.
1109
+ */
1110
+ waitForBodyIdle?: () => {
1111
+ promise: Promise<void>;
1112
+ cancel: () => void;
1113
+ } | null;
1114
+ /** Unpark body idle if a full-body speak is cancelled before playback. */
1115
+ onBodyIdleCancelled?: () => void;
965
1116
  /** Redis brain id (from getAiTwin `brainId`). Sent as `brainId` on `/ws/voice`. */
966
1117
  brainId?: string;
967
1118
  /** @deprecated Use `brainId`. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoji/aitwin",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "description": "AiTwin.me Player SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/aitwin.cjs",