@voqalize/avatar 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE-CC-BY-4.0 +396 -0
  2. package/README.md +65 -17
  3. package/assets/README.md +48 -0
  4. package/assets/tanya.glb +0 -0
  5. package/assets/tara.glb +0 -0
  6. package/assets/tushar.glb +0 -0
  7. package/client/AvatarClient.ts +337 -42
  8. package/client/arjun.ts +2 -0
  9. package/client/createAvatar.ts +38 -0
  10. package/client/index.ts +6 -1
  11. package/client/internal.ts +31 -3
  12. package/client/ishita.ts +2 -0
  13. package/client/kabir.ts +2 -0
  14. package/client/meera.ts +2 -0
  15. package/client/naina.ts +2 -0
  16. package/client/playout.ts +95 -0
  17. package/client/supports.ts +28 -0
  18. package/client/three/assets.ts +22 -0
  19. package/client/three/budgets.ts +27 -0
  20. package/client/three/holds.ts +64 -0
  21. package/client/three/internal.ts +54 -0
  22. package/client/three/motion-limits.json +116 -0
  23. package/client/three/sequences.ts +281 -0
  24. package/client/three/tanya-asset.ts +6 -0
  25. package/client/three/tanya.ts +69 -0
  26. package/client/three/tara-asset.ts +25 -0
  27. package/client/three/tara-rig.ts +1571 -0
  28. package/client/three/tara.ts +77 -0
  29. package/client/three/tushar-asset.ts +6 -0
  30. package/client/three/tushar.ts +65 -0
  31. package/client/types.ts +109 -20
  32. package/client/vikram.ts +2 -0
  33. package/dist/AvatarClient.d.ts +89 -11
  34. package/dist/AvatarClient.d.ts.map +1 -1
  35. package/dist/AvatarClient.js +297 -35
  36. package/dist/AvatarClient.js.map +1 -1
  37. package/dist/arjun.d.ts +1 -0
  38. package/dist/arjun.d.ts.map +1 -1
  39. package/dist/arjun.js +2 -0
  40. package/dist/arjun.js.map +1 -1
  41. package/dist/createAvatar.d.ts +36 -0
  42. package/dist/createAvatar.d.ts.map +1 -1
  43. package/dist/createAvatar.js.map +1 -1
  44. package/dist/index.d.ts +6 -2
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +5 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/internal.d.ts +9 -5
  49. package/dist/internal.d.ts.map +1 -1
  50. package/dist/internal.js +13 -5
  51. package/dist/internal.js.map +1 -1
  52. package/dist/ishita.d.ts +1 -0
  53. package/dist/ishita.d.ts.map +1 -1
  54. package/dist/ishita.js +2 -0
  55. package/dist/ishita.js.map +1 -1
  56. package/dist/kabir.d.ts +1 -0
  57. package/dist/kabir.d.ts.map +1 -1
  58. package/dist/kabir.js +2 -0
  59. package/dist/kabir.js.map +1 -1
  60. package/dist/meera.d.ts +1 -0
  61. package/dist/meera.d.ts.map +1 -1
  62. package/dist/meera.js +2 -0
  63. package/dist/meera.js.map +1 -1
  64. package/dist/naina.d.ts +1 -0
  65. package/dist/naina.d.ts.map +1 -1
  66. package/dist/naina.js +2 -0
  67. package/dist/naina.js.map +1 -1
  68. package/dist/playout.d.ts +42 -0
  69. package/dist/playout.d.ts.map +1 -0
  70. package/dist/playout.js +85 -0
  71. package/dist/playout.js.map +1 -0
  72. package/dist/supports.d.ts +20 -0
  73. package/dist/supports.d.ts.map +1 -0
  74. package/dist/supports.js +26 -0
  75. package/dist/supports.js.map +1 -0
  76. package/dist/three/assets.d.ts +8 -0
  77. package/dist/three/assets.d.ts.map +1 -0
  78. package/dist/three/assets.js +19 -0
  79. package/dist/three/assets.js.map +1 -0
  80. package/dist/three/budgets.d.ts +17 -0
  81. package/dist/three/budgets.d.ts.map +1 -0
  82. package/dist/three/budgets.js +21 -0
  83. package/dist/three/budgets.js.map +1 -0
  84. package/dist/three/holds.d.ts +33 -0
  85. package/dist/three/holds.d.ts.map +1 -0
  86. package/dist/three/holds.js +56 -0
  87. package/dist/three/holds.js.map +1 -0
  88. package/dist/three/internal.d.ts +52 -0
  89. package/dist/three/internal.d.ts.map +1 -0
  90. package/dist/three/internal.js +49 -0
  91. package/dist/three/internal.js.map +1 -0
  92. package/dist/three/motion-limits.json +116 -0
  93. package/dist/three/sequences.d.ts +71 -0
  94. package/dist/three/sequences.d.ts.map +1 -0
  95. package/dist/three/sequences.js +262 -0
  96. package/dist/three/sequences.js.map +1 -0
  97. package/dist/three/tanya-asset.d.ts +7 -0
  98. package/dist/three/tanya-asset.d.ts.map +1 -0
  99. package/dist/three/tanya-asset.js +7 -0
  100. package/dist/three/tanya-asset.js.map +1 -0
  101. package/dist/three/tanya.d.ts +35 -0
  102. package/dist/three/tanya.d.ts.map +1 -0
  103. package/dist/three/tanya.js +51 -0
  104. package/dist/three/tanya.js.map +1 -0
  105. package/dist/three/tara-asset.d.ts +26 -0
  106. package/dist/three/tara-asset.d.ts.map +1 -0
  107. package/dist/three/tara-asset.js +26 -0
  108. package/dist/three/tara-asset.js.map +1 -0
  109. package/dist/three/tara-rig.d.ts +409 -0
  110. package/dist/three/tara-rig.d.ts.map +1 -0
  111. package/dist/three/tara-rig.js +1504 -0
  112. package/dist/three/tara-rig.js.map +1 -0
  113. package/dist/three/tara.d.ts +35 -0
  114. package/dist/three/tara.d.ts.map +1 -0
  115. package/dist/three/tara.js +59 -0
  116. package/dist/three/tara.js.map +1 -0
  117. package/dist/three/tushar-asset.d.ts +7 -0
  118. package/dist/three/tushar-asset.d.ts.map +1 -0
  119. package/dist/three/tushar-asset.js +7 -0
  120. package/dist/three/tushar-asset.js.map +1 -0
  121. package/dist/three/tushar.d.ts +31 -0
  122. package/dist/three/tushar.d.ts.map +1 -0
  123. package/dist/three/tushar.js +47 -0
  124. package/dist/three/tushar.js.map +1 -0
  125. package/dist/types.d.ts +65 -10
  126. package/dist/types.d.ts.map +1 -1
  127. package/dist/types.js +58 -11
  128. package/dist/types.js.map +1 -1
  129. package/dist/vikram.d.ts +1 -0
  130. package/dist/vikram.d.ts.map +1 -1
  131. package/dist/vikram.js +2 -0
  132. package/dist/vikram.js.map +1 -1
  133. package/package.json +34 -6
  134. package/src/avatar.d.ts +59 -2
  135. package/src/avatar.js +743 -94
  136. package/src/behavior.d.ts +28 -12
  137. package/src/behavior.js +54 -42
  138. package/src/canvas/create-rig.js +1 -1
  139. package/src/canvas/src/live.js +2 -2
  140. package/src/conformance.js +1 -1
  141. package/src/emotions.js +4 -2
  142. package/src/gaze.js +334 -73
  143. package/src/head.js +134 -0
  144. package/src/idle.js +210 -19
  145. package/src/interjections.js +70 -26
  146. package/src/prosody.js +647 -0
  147. package/src/visemes.js +85 -15
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@voqalize/avatar",
3
- "version": "0.3.0",
4
- "description": "A JavaScript-programmable 2-D talking head for AI voice calls: server-synced lipsync, state through motion, zero dependencies.",
5
- "license": "MIT",
3
+ "version": "0.4.1",
4
+ "description": "A JavaScript-programmable talking head for AI voice calls: line-art or 2.5-D faces, server-synced lipsync, state through motion, no runtime dependencies.",
5
+ "license": "MIT AND CC-BY-4.0",
6
6
  "author": "Voqalize",
7
7
  "homepage": "https://github.com/voqalize/avatar#readme",
8
8
  "repository": {
@@ -22,7 +22,9 @@
22
22
  "pipecat",
23
23
  "voice-agent",
24
24
  "svg",
25
- "animation"
25
+ "animation",
26
+ "3d",
27
+ "threejs"
26
28
  ],
27
29
  "engines": {
28
30
  "node": ">=20"
@@ -47,6 +49,10 @@
47
49
  "types": "./dist/internal.d.ts",
48
50
  "default": "./dist/internal.js"
49
51
  },
52
+ "./internal/three": {
53
+ "types": "./dist/three/internal.d.ts",
54
+ "default": "./dist/three/internal.js"
55
+ },
50
56
  "./faces/peep": {
51
57
  "types": "./src/face-peep.d.ts",
52
58
  "default": "./src/face-peep.js"
@@ -59,6 +65,18 @@
59
65
  "types": "./src/face-myna.d.ts",
60
66
  "default": "./src/face-myna.js"
61
67
  },
68
+ "./avatars/tara": {
69
+ "types": "./dist/three/tara.d.ts",
70
+ "default": "./dist/three/tara.js"
71
+ },
72
+ "./avatars/tushar": {
73
+ "types": "./dist/three/tushar.d.ts",
74
+ "default": "./dist/three/tushar.js"
75
+ },
76
+ "./avatars/tanya": {
77
+ "types": "./dist/three/tanya.d.ts",
78
+ "default": "./dist/three/tanya.js"
79
+ },
62
80
  "./avatars/arjun": {
63
81
  "types": "./dist/arjun.d.ts",
64
82
  "default": "./dist/arjun.js"
@@ -112,7 +130,9 @@
112
130
  "files": [
113
131
  "src",
114
132
  "client",
115
- "dist"
133
+ "dist",
134
+ "assets",
135
+ "LICENSE-CC-BY-4.0"
116
136
  ],
117
137
  "scripts": {
118
138
  "build": "tsc -p tsconfig.json",
@@ -122,7 +142,8 @@
122
142
  "peerDependencies": {
123
143
  "@pipecat-ai/client-js": ">=1.4 <2",
124
144
  "react": ">=18",
125
- "react-dom": ">=18"
145
+ "react-dom": ">=18",
146
+ "three": ">=0.180 <0.187"
126
147
  },
127
148
  "peerDependenciesMeta": {
128
149
  "@pipecat-ai/client-js": {
@@ -133,6 +154,13 @@
133
154
  },
134
155
  "react-dom": {
135
156
  "optional": true
157
+ },
158
+ "three": {
159
+ "optional": true
136
160
  }
161
+ },
162
+ "devDependencies": {
163
+ "@types/three": "^0.185.4",
164
+ "three": "^0.180.0"
137
165
  }
138
166
  }
package/src/avatar.d.ts CHANGED
@@ -60,6 +60,7 @@ export type AvatarGazeName =
60
60
  | "AWAY_THINKING"
61
61
  | "AWAY_RIGHT"
62
62
  | "AWAY_DOWN"
63
+ | "AWAY_SIDE"
63
64
  | "CUSTOM";
64
65
 
65
66
  /** The complete server-addressable action contract. Names are semantic, not
@@ -174,8 +175,15 @@ export interface AvatarApi {
174
175
  speak(o?: SpeakOptions): AvatarApi;
175
176
  pushCues(cues: Cue[]): AvatarApi;
176
177
  stopSpeaking(): AvatarApi;
177
- /** Self-completing action: states resolve underneath while motion lands. */
178
- action(id: AvatarActionId): AvatarApi;
178
+ /**
179
+ * Self-completing action: states resolve underneath while motion lands.
180
+ *
181
+ * One core intent, one of `actions`, or one of `sequences` — the vocabulary
182
+ * is open, so an id this face has no word for is a no-op rather than a
183
+ * throw. `ACKNOWLEDGE` resolves to whichever of this body's acknowledgements
184
+ * the moment calls for.
185
+ */
186
+ action(id: string): AvatarApi;
179
187
  setHandSide(dir: HandSide): AvatarApi;
180
188
  perform(actions: AvatarAction[], o?: PerformOptions): PerformHandle;
181
189
  setUserSpeaking(speaking: boolean | null): AvatarApi;
@@ -253,12 +261,53 @@ export interface CreateAvatarOptions {
253
261
  mouthGain?: Gain;
254
262
  gestureGain?: Gain;
255
263
  motionGain?: Gain;
264
+ /** Speech-rhythm head motion (beats, phrase drift), 0..2. A per-rig
265
+ * calibration: the same pose unit is a different angle on every rig. */
266
+ prosodyHeadGain?: Gain;
267
+ /** Speech-rhythm face motion (brows, lids, turn-edge warmth), 0..2. */
268
+ prosodyFaceGain?: Gain;
269
+ /** The share of a sustained head turn the trunk takes up, 0..1. Default
270
+ * 0.45; a per-rig calibration, like `prosodyHeadGain`. */
271
+ trunkFollow?: number;
272
+ /**
273
+ * How far this face may *hold* its head off centre, per axis, in pose units.
274
+ * The layers that hold a pose — attitude, gaze, a phrase's pose, the idle
275
+ * posture — are folded into this together; strokes, beats and clip deltas
276
+ * are not, so a nod keeps its peak. An axis left out is unbudgeted.
277
+ *
278
+ * A per-rig fact and a measured one: what a face can hold before its
279
+ * rendering gives it away is a property of that drawing or that photograph,
280
+ * and the library has no way to guess it.
281
+ */
282
+ headHold?: Readonly<Partial<Record<"headYaw" | "headPitch" | "headRoll", number>>>;
256
283
  /** Disable only the bundled SVG hand renderer. A custom rig still receives
257
284
  * first-class `frame.hand` controls for every gesture action. Default true. */
258
285
  hand?: boolean;
259
286
  handSide?: HandSide;
260
287
  /** Withhold the rAF loop so a tool can drive frames itself via `step(dt)`. */
261
288
  manual?: boolean;
289
+ /**
290
+ * This avatar's own addressable motions, on top of the core intents. A
291
+ * server names one with the wire's `action` command, same as a core one; a
292
+ * face that does not have the name ignores it. Keyed by id, each value a clip
293
+ * in the same shape `ACTIONS` uses. Cannot shadow one of this renderer's own
294
+ * — `ACTIONS` wins.
295
+ */
296
+ sequences?: Readonly<Record<string, unknown>>;
297
+ /**
298
+ * This avatar's own shape for one of this renderer's actions, keyed by its
299
+ * id. Same id, same intent, a rendering sized for this body — the shared
300
+ * clips are authored for a line face. An id this renderer does not publish
301
+ * throws: this can reshape the vocabulary, never add to it.
302
+ */
303
+ actions?: Readonly<Record<string, unknown>>;
304
+ /**
305
+ * This avatar's own rendering of a state, keyed by state name. Each value
306
+ * replaces that state's fields whole (`pose`, `idle`, …); the rest are the
307
+ * shared table's. A name that is not a state throws: this can re-render the
308
+ * vocabulary, never add to it.
309
+ */
310
+ states?: Readonly<Partial<Record<AvatarStateName, Readonly<Record<string, unknown>>>>>;
262
311
  }
263
312
 
264
313
  export function createAvatar(opts: CreateAvatarOptions): AvatarApi;
@@ -279,10 +328,18 @@ export function checkHandFraming(meta: AvatarMeta): {
279
328
  outboardLimit: number;
280
329
  worst: Record<string, number>;
281
330
  };
331
+ /** The neutral pose: every channel's resting value (`src/params.js`). */
332
+ export const REST: Readonly<Record<PoseChannel, number>>;
333
+ /** Every channel name, in `REST` order. */
334
+ export const CHANNELS: readonly PoseChannel[];
335
+ /** Post-mix clamp per channel, `[min, max]`. */
336
+ export const RANGE: Readonly<Record<PoseChannel, readonly [number, number]>>;
282
337
  export const VISEME_LETTERS: readonly VisemeLetter[];
283
338
  export const VISEME_SHAPES: Readonly<Record<VisemeLetter, PoseOverrides>>;
284
339
  /** Cues lead the audio by this many ms — perceptual tolerance is asymmetric. */
285
340
  export const LEAD_MS: number;
341
+ /** The shoulder line's share of a held `headRoll`, per pose unit. */
342
+ export const SHOULDER_TILT: number;
286
343
  export const ARPABET_TO_VISEME: Readonly<Record<string, VisemeLetter>>;
287
344
  export const AZURE_VISEME_TO_LETTER: Readonly<Record<number, VisemeLetter>>;
288
345