@lovelace_lol/polymer 0.0.7 → 0.0.8
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/README.md +434 -12
- package/dist/index.d.ts +1945 -244
- package/dist/index.js +1686 -1017
- package/dist/vision/face-worker.js +296 -0
- package/dist/vision/face_landmarker.task +0 -0
- package/dist/vision/manifest.edn +1 -0
- package/dist/vision/vision_bundle.js +2 -0
- package/dist/vision/wasm/vision_wasm_internal.js +8841 -0
- package/dist/vision/wasm/vision_wasm_internal.wasm +0 -0
- package/dist/vision/wasm/vision_wasm_module_internal.js +8837 -0
- package/dist/vision/wasm/vision_wasm_module_internal.wasm +0 -0
- package/dist/vision/wasm/vision_wasm_nosimd_internal.js +8832 -0
- package/dist/vision/wasm/vision_wasm_nosimd_internal.wasm +0 -0
- package/dist/worker/agency-worker.js +1276 -962
- package/dist/worker/manifest.edn +1 -1
- package/package.json +33 -20
- package/dist/test.cjs +0 -1519
- package/shadow-cljs.edn +0 -173
- package/src/polymer/animation/agency.cljs +0 -84
- package/src/polymer/animation/domain.cljs +0 -110
- package/src/polymer/animation/planner.cljs +0 -88
- package/src/polymer/animation/runtime.cljs +0 -137
- package/src/polymer/animation/scheduler.cljs +0 -178
- package/src/polymer/animation/service.cljs +0 -981
- package/src/polymer/animation/state.cljs +0 -112
- package/src/polymer/blink/agency.cljs +0 -131
- package/src/polymer/blink/planner.cljs +0 -115
- package/src/polymer/blink/scheduler.cljs +0 -90
- package/src/polymer/blink/snippet.cljs +0 -50
- package/src/polymer/blink/state.cljs +0 -102
- package/src/polymer/camera_context/agency.cljs +0 -132
- package/src/polymer/camera_context/domain.cljs +0 -186
- package/src/polymer/camera_context/planner.cljs +0 -50
- package/src/polymer/camera_context/scheduler.cljs +0 -113
- package/src/polymer/camera_context/state.cljs +0 -121
- package/src/polymer/character.cljs +0 -403
- package/src/polymer/conversation/agency.cljs +0 -83
- package/src/polymer/conversation/domain.cljs +0 -35
- package/src/polymer/conversation/effector.cljs +0 -130
- package/src/polymer/conversation/planner.cljs +0 -178
- package/src/polymer/conversation/scheduler.cljs +0 -202
- package/src/polymer/conversation/service.cljs +0 -329
- package/src/polymer/conversation/state.cljs +0 -186
- package/src/polymer/core.cljs +0 -172
- package/src/polymer/eye_head/agency.cljs +0 -75
- package/src/polymer/eye_head/domain.cljs +0 -133
- package/src/polymer/eye_head/goap.cljs +0 -106
- package/src/polymer/eye_head/scheduler.cljs +0 -176
- package/src/polymer/eye_head/service.cljs +0 -259
- package/src/polymer/eye_head/snippet.cljs +0 -92
- package/src/polymer/eye_head/state.cljs +0 -167
- package/src/polymer/gaze/agency.cljs +0 -85
- package/src/polymer/gaze/domain.cljs +0 -211
- package/src/polymer/gaze/goap.cljs +0 -208
- package/src/polymer/gaze/scheduler.cljs +0 -184
- package/src/polymer/gaze/state.cljs +0 -202
- package/src/polymer/gesture/agency.cljs +0 -185
- package/src/polymer/gesture/goap.cljs +0 -461
- package/src/polymer/gesture/scheduler.cljs +0 -122
- package/src/polymer/gesture/snippet.cljs +0 -198
- package/src/polymer/gesture/state.cljs +0 -273
- package/src/polymer/lipsync/agency.cljs +0 -593
- package/src/polymer/lipsync/articulation/jaw.cljs +0 -258
- package/src/polymer/lipsync/articulation/snippet.cljs +0 -605
- package/src/polymer/lipsync/articulation/tongue.cljs +0 -418
- package/src/polymer/lipsync/articulation/visemes.cljs +0 -429
- package/src/polymer/lipsync/goap.cljs +0 -132
- package/src/polymer/lipsync/pronunciation/effector.cljs +0 -51
- package/src/polymer/lipsync/scheduler.cljs +0 -302
- package/src/polymer/lipsync/state.cljs +0 -202
- package/src/polymer/nlp/phonemes.cljs +0 -164
- package/src/polymer/prosodic/agency.cljs +0 -196
- package/src/polymer/prosodic/goap.cljs +0 -122
- package/src/polymer/prosodic/scheduler.cljs +0 -99
- package/src/polymer/prosodic/snippet.cljs +0 -106
- package/src/polymer/prosodic/state.cljs +0 -139
- package/src/polymer/runtime/embody.cljs +0 -117
- package/src/polymer/runtime/embody_wasm.cljs +0 -177
- package/src/polymer/runtime/rust_embody_host.cljs +0 -647
- package/src/polymer/society.cljs +0 -253
- package/src/polymer/stream.cljs +0 -130
- package/src/polymer/transcription/agency.cljs +0 -69
- package/src/polymer/transcription/domain.cljs +0 -68
- package/src/polymer/transcription/effector.cljs +0 -611
- package/src/polymer/transcription/planner.cljs +0 -203
- package/src/polymer/transcription/scheduler.cljs +0 -225
- package/src/polymer/transcription/service.cljs +0 -209
- package/src/polymer/transcription/state.cljs +0 -239
- package/src/polymer/tts/agency.cljs +0 -503
- package/src/polymer/tts/azure.cljs +0 -290
- package/src/polymer/tts/planner.cljs +0 -178
- package/src/polymer/tts/runtime.cljs +0 -624
- package/src/polymer/tts/scheduler.cljs +0 -162
- package/src/polymer/tts/state.cljs +0 -191
- package/src/polymer/worker.cljs +0 -81
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,523 @@
|
|
|
1
|
+
// This hand-authored declaration file is package source. `pnpm build` copies it
|
|
2
|
+
// into dist/ beside the generated ClojureScript artifacts.
|
|
1
3
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
AnimationClip,
|
|
5
|
+
Camera,
|
|
6
|
+
ColorRepresentation,
|
|
7
|
+
Mesh,
|
|
8
|
+
Object3D,
|
|
9
|
+
PerspectiveCamera,
|
|
10
|
+
Scene,
|
|
11
|
+
Texture,
|
|
12
|
+
Vector3,
|
|
13
|
+
WebGLRenderer,
|
|
14
|
+
} from 'three';
|
|
15
|
+
import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
16
|
+
import type { ThreeModelReferencePose as EmbodyModelReferencePose } from '@lovelace_lol/embody/three';
|
|
17
|
+
export type ThreeModelReferencePose = EmbodyModelReferencePose;
|
|
18
|
+
import type {
|
|
19
|
+
CharacterSceneRenderer,
|
|
20
|
+
CharacterSceneBackend,
|
|
21
|
+
DefaultCharacterSceneAsyncOptions,
|
|
22
|
+
ReadyDefaultCharacterScene,
|
|
23
|
+
DefaultCharacterSceneRuntime,
|
|
24
|
+
DefaultCharacterSceneRuntimeOptions,
|
|
25
|
+
CharacterSceneRenderingController,
|
|
26
|
+
} from '@lovelace_lol/embody/three';
|
|
27
|
+
export type {
|
|
28
|
+
CharacterSceneRendererPreference,
|
|
29
|
+
CharacterSceneRenderer,
|
|
30
|
+
CharacterSceneBackend,
|
|
31
|
+
DefaultCharacterSceneAsyncOptions,
|
|
32
|
+
ReadyDefaultCharacterScene,
|
|
33
|
+
DefaultCharacterSceneRuntime,
|
|
34
|
+
DefaultCharacterSceneRuntimeOptions,
|
|
35
|
+
CharacterSceneRenderingSettings,
|
|
36
|
+
CharacterSceneRenderingStatus,
|
|
37
|
+
CharacterSceneRenderingSnapshot,
|
|
38
|
+
CharacterSceneRenderingController,
|
|
39
|
+
CharacterSceneRendererLease,
|
|
40
|
+
} from '@lovelace_lol/embody/three';
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/** Capture before playback or profile application; retain for engine recreation. */
|
|
44
|
+
export declare function captureModelReferencePose(model: Object3D): ThreeModelReferencePose;
|
|
45
|
+
|
|
46
|
+
export type PresetType = 'cc4' | 'fish' | string;
|
|
47
|
+
export type BoneAxisKey = 'pitch' | 'yaw' | 'roll';
|
|
48
|
+
export type BoneAxisDirection = 'negative' | 'positive';
|
|
49
|
+
export type BoneAxisDirectionScale = -1 | 1;
|
|
50
|
+
export type RotationChannel = 'rx' | 'ry' | 'rz';
|
|
51
|
+
export type BilateralBoneAxisScope = 'shared' | 'left' | 'right';
|
|
52
|
+
export type BoneControlFamily = 'Horizontal Gaze' | 'Vertical Gaze';
|
|
53
|
+
export type BoneControlScope = 'Both Eyes' | 'Left Eye Only' | 'Right Eye Only';
|
|
54
|
+
export type HumanoidSkeletonTemplateVec3 = readonly [number, number, number];
|
|
55
|
+
export type HumanoidSkeletonTemplateBounds = readonly [number, number, number, number, number, number];
|
|
56
|
+
export type MorphTargetRef = string | number;
|
|
57
|
+
export type MeshCategory = 'body' | 'eye' | 'eyeOcclusion' | 'tearLine' | 'teeth' | 'tongue' | 'hair' | 'eyebrow' | 'cornea' | 'eyelash';
|
|
58
|
+
export type BlendingMode = 'Normal' | 'Additive' | 'Subtractive' | 'Multiply' | 'None';
|
|
59
|
+
|
|
60
|
+
export interface MorphTargetsBySide {
|
|
61
|
+
left: MorphTargetRef[];
|
|
62
|
+
right: MorphTargetRef[];
|
|
63
|
+
center: MorphTargetRef[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface BoneBinding {
|
|
67
|
+
node: string;
|
|
68
|
+
channel: 'rx' | 'ry' | 'rz' | 'tx' | 'ty' | 'tz';
|
|
69
|
+
scale: BoneAxisDirectionScale;
|
|
70
|
+
maxDegrees?: number;
|
|
71
|
+
maxUnits?: number;
|
|
72
|
+
side?: 'left' | 'right';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface AUInfo {
|
|
76
|
+
id: string;
|
|
77
|
+
name: string;
|
|
78
|
+
muscularBasis?: string;
|
|
79
|
+
links?: string[];
|
|
80
|
+
faceArea?: 'Upper' | 'Lower' | 'Body';
|
|
81
|
+
facePart?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface RotationAxis {
|
|
85
|
+
aus: number[];
|
|
86
|
+
axis: RotationChannel;
|
|
87
|
+
negative?: number | number[];
|
|
88
|
+
positive?: number | number[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface CompositeRotation {
|
|
92
|
+
node: string;
|
|
93
|
+
pitch: RotationAxis | null;
|
|
94
|
+
yaw: RotationAxis | null;
|
|
95
|
+
roll: RotationAxis | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface VisemeSlotFeatures {
|
|
99
|
+
jawOpen?: number;
|
|
100
|
+
lipClosed?: number;
|
|
101
|
+
lipRound?: number;
|
|
102
|
+
lipSpread?: number;
|
|
103
|
+
tongueTip?: number;
|
|
104
|
+
fricative?: number;
|
|
105
|
+
nasal?: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface VisemeSlot {
|
|
109
|
+
id: string;
|
|
110
|
+
label: string;
|
|
111
|
+
order?: number;
|
|
112
|
+
providerIds?: Record<string, Array<string | number>>;
|
|
113
|
+
phonemes?: string[];
|
|
114
|
+
matchers?: string[];
|
|
115
|
+
features?: VisemeSlotFeatures;
|
|
116
|
+
defaultJawAmount?: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type VisemeTongueTarget = Record<string, number>;
|
|
120
|
+
|
|
121
|
+
export interface VisemeBindingTarget {
|
|
122
|
+
morph: MorphTargetRef;
|
|
123
|
+
weight?: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface VisemeBinding {
|
|
127
|
+
targets?: VisemeBindingTarget[];
|
|
128
|
+
morph?: MorphTargetRef;
|
|
129
|
+
jawAmount?: number;
|
|
130
|
+
note?: string;
|
|
131
|
+
sharedWith?: string[];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface ResolvedVisemeSlot extends Omit<VisemeSlot, 'label'> {
|
|
135
|
+
label?: string;
|
|
136
|
+
[extension: string]: unknown;
|
|
137
|
+
}
|
|
138
|
+
/** Model-independent authored resolution. Array indices equal Embody runtime slot indices. */
|
|
139
|
+
export interface ResolvedVisemeProfile {
|
|
140
|
+
routingMode: 'explicit' | 'legacy';
|
|
141
|
+
/** Stock canonical sound index to runtime slot index, including reordered stock profiles. */
|
|
142
|
+
canonicalSlotIndices?: number[];
|
|
143
|
+
visemeSlots: ResolvedVisemeSlot[];
|
|
144
|
+
visemeBindingTargets: Array<Array<Required<VisemeBindingTarget>>>;
|
|
145
|
+
visemeJawAmounts: number[];
|
|
146
|
+
visemeTongueTargets: VisemeTongueTarget[];
|
|
147
|
+
visemeMeshNames: string[];
|
|
148
|
+
visemeMeshCategory: string;
|
|
149
|
+
}
|
|
150
|
+
/** Requires initEmbodyCore(); does not verify target existence on a loaded model. */
|
|
151
|
+
export declare function resolveVisemeProfile(profile: Partial<Profile>): ResolvedVisemeProfile;
|
|
152
|
+
|
|
153
|
+
export interface MappingEditorSection {
|
|
154
|
+
id: string;
|
|
155
|
+
label: string;
|
|
156
|
+
kind: 'au' | 'viseme' | 'lipSync' | 'hair' | 'unmapped' | 'custom';
|
|
157
|
+
order: number;
|
|
158
|
+
meshCategory?: string;
|
|
159
|
+
facePart?: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface MeshMaterialSettings {
|
|
163
|
+
renderOrder?: number;
|
|
164
|
+
transparent?: boolean;
|
|
165
|
+
opacity?: number;
|
|
166
|
+
depthWrite?: boolean;
|
|
167
|
+
depthTest?: boolean;
|
|
168
|
+
blending?: BlendingMode;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface MeshInfo {
|
|
172
|
+
name?: string;
|
|
173
|
+
visible?: boolean;
|
|
174
|
+
category: MeshCategory;
|
|
175
|
+
morphCount: number;
|
|
176
|
+
material?: MeshMaterialSettings;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export type HairMorphAxis = 'yaw' | 'pitch' | 'roll';
|
|
180
|
+
export interface HairMorphTargetMapping { key: string; axis: HairMorphAxis; }
|
|
181
|
+
export interface HairMorphTargetValueMapping { value: number; axis: HairMorphAxis; }
|
|
182
|
+
export interface HairPhysicsProfileConfig {
|
|
183
|
+
enabled?: boolean;
|
|
184
|
+
stiffness?: number;
|
|
185
|
+
damping?: number;
|
|
186
|
+
inertia?: number;
|
|
187
|
+
gravity?: number;
|
|
188
|
+
responseScale?: number;
|
|
189
|
+
idleSwayAmount?: number;
|
|
190
|
+
idleSwaySpeed?: number;
|
|
191
|
+
windStrength?: number;
|
|
192
|
+
windDirectionX?: number;
|
|
193
|
+
windDirectionZ?: number;
|
|
194
|
+
windTurbulence?: number;
|
|
195
|
+
windFrequency?: number;
|
|
196
|
+
idleClipDuration?: number;
|
|
197
|
+
impulseClipDuration?: number;
|
|
198
|
+
direction?: { yawSign?: 1 | -1; pitchSign?: 1 | -1 };
|
|
199
|
+
morphTargets?: {
|
|
200
|
+
swayLeft?: HairMorphTargetMapping;
|
|
201
|
+
swayRight?: HairMorphTargetMapping;
|
|
202
|
+
swayFront?: HairMorphTargetMapping;
|
|
203
|
+
fluffRight?: HairMorphTargetMapping;
|
|
204
|
+
fluffBottom?: HairMorphTargetMapping;
|
|
205
|
+
headUp?: Record<string, HairMorphTargetValueMapping>;
|
|
206
|
+
headDown?: Record<string, HairMorphTargetValueMapping>;
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export type VRMHumanoidRole =
|
|
211
|
+
| 'hips' | 'spine' | 'chest' | 'upperChest' | 'neck' | 'head' | 'leftEye' | 'rightEye' | 'jaw'
|
|
212
|
+
| 'leftShoulder' | 'leftUpperArm' | 'leftLowerArm' | 'leftHand'
|
|
213
|
+
| 'rightShoulder' | 'rightUpperArm' | 'rightLowerArm' | 'rightHand'
|
|
214
|
+
| 'leftUpperLeg' | 'leftLowerLeg' | 'leftFoot' | 'leftToes'
|
|
215
|
+
| 'rightUpperLeg' | 'rightLowerLeg' | 'rightFoot' | 'rightToes'
|
|
216
|
+
| 'leftThumbMetacarpal' | 'leftThumbProximal' | 'leftThumbDistal'
|
|
217
|
+
| 'rightThumbMetacarpal' | 'rightThumbProximal' | 'rightThumbDistal'
|
|
218
|
+
| 'leftIndexProximal' | 'leftIndexIntermediate' | 'leftIndexDistal'
|
|
219
|
+
| 'rightIndexProximal' | 'rightIndexIntermediate' | 'rightIndexDistal'
|
|
220
|
+
| 'leftMiddleProximal' | 'leftMiddleIntermediate' | 'leftMiddleDistal'
|
|
221
|
+
| 'rightMiddleProximal' | 'rightMiddleIntermediate' | 'rightMiddleDistal'
|
|
222
|
+
| 'leftRingProximal' | 'leftRingIntermediate' | 'leftRingDistal'
|
|
223
|
+
| 'rightRingProximal' | 'rightRingIntermediate' | 'rightRingDistal'
|
|
224
|
+
| 'leftLittleProximal' | 'leftLittleIntermediate' | 'leftLittleDistal'
|
|
225
|
+
| 'rightLittleProximal' | 'rightLittleIntermediate' | 'rightLittleDistal';
|
|
226
|
+
|
|
227
|
+
/** A standard bone role; motion axes/ranges belong to the authored rig profile. */
|
|
228
|
+
export interface HumanoidBoneDefinition {
|
|
229
|
+
role: VRMHumanoidRole;
|
|
230
|
+
label: string;
|
|
231
|
+
section: 'Torso' | 'Head' | 'Arms' | 'Hands' | 'Legs' | 'Feet';
|
|
232
|
+
parent: VRMHumanoidRole | null;
|
|
233
|
+
required: boolean;
|
|
234
|
+
/** This optional parent must be mapped when the child is mapped. */
|
|
235
|
+
requiresParent: boolean;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface HumanoidSpecification {
|
|
239
|
+
standard: 'VRMC_vrm-1.0';
|
|
240
|
+
bones: HumanoidBoneDefinition[];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface HumanoidRoleBinding {
|
|
244
|
+
nodeKey: string;
|
|
245
|
+
/** Literal model bone selected by the role editor, before preset prefix lookup. */
|
|
246
|
+
exactBoneName?: string;
|
|
247
|
+
source?: string;
|
|
248
|
+
confidence?: number;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export interface HumanoidCharacterization {
|
|
252
|
+
schemaVersion: 1;
|
|
253
|
+
standard: 'VRMC_vrm-1.0';
|
|
254
|
+
status: 'verified-vrm' | 'characterized' | 'incomplete';
|
|
255
|
+
/** Explicitly edited role catalogs are authoritative across preset upgrades. */
|
|
256
|
+
authored?: boolean;
|
|
257
|
+
roles: Partial<Record<VRMHumanoidRole, HumanoidRoleBinding>>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export interface HumanoidCharacterizationResolution {
|
|
261
|
+
schemaVersion: number | null;
|
|
262
|
+
standard: string | null;
|
|
263
|
+
status: string | null;
|
|
264
|
+
roles: Record<string, { nodeKey: string; boneName: string; source: string | null; confidence: number | null }>;
|
|
265
|
+
missingRequiredRoles: string[];
|
|
266
|
+
errors: string[];
|
|
267
|
+
warnings: string[];
|
|
268
|
+
valid: boolean;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Semantic body actions reuse the AU bone/morph evaluator. VRM names identify targets. */
|
|
272
|
+
export interface BodyControlDefinition {
|
|
273
|
+
label: string;
|
|
274
|
+
section: string;
|
|
275
|
+
auId: number;
|
|
276
|
+
negativeAuId?: number | null;
|
|
277
|
+
bilateral: boolean;
|
|
278
|
+
roles: VRMHumanoidRole[];
|
|
279
|
+
order?: number;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface BodyControlDescriptor {
|
|
283
|
+
id: string;
|
|
284
|
+
label: string;
|
|
285
|
+
section: string;
|
|
286
|
+
auId: number;
|
|
287
|
+
negativeAuId: number | null;
|
|
288
|
+
auIds: number[];
|
|
289
|
+
bilateral: boolean;
|
|
290
|
+
roles: VRMHumanoidRole[];
|
|
291
|
+
order: number;
|
|
292
|
+
boneBindings: Array<BoneBinding & { auId: number; boneName: string }>;
|
|
293
|
+
morphBindings: MorphTargetsBySide;
|
|
294
|
+
meshNames: string[];
|
|
295
|
+
hasBones: boolean;
|
|
296
|
+
hasMorphs: boolean;
|
|
297
|
+
isMixed: boolean;
|
|
298
|
+
available: boolean;
|
|
299
|
+
diagnostics: string[];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** Pose values are normalized authored action amounts, never world Euler angles. */
|
|
303
|
+
export interface SemanticPoseChannel {
|
|
304
|
+
intensity: number;
|
|
305
|
+
/** -1 = character's left, 0 = both, +1 = character's right. */
|
|
306
|
+
balance?: number;
|
|
307
|
+
/** Morph contribution only; bone activation remains intensity. Defaults to profile. */
|
|
308
|
+
morphStrength?: number;
|
|
309
|
+
}
|
|
310
|
+
export interface SemanticPose {
|
|
311
|
+
version: 1;
|
|
312
|
+
controls: Array<{ controlId: string; positive?: SemanticPoseChannel; negative?: SemanticPoseChannel }>;
|
|
313
|
+
}
|
|
314
|
+
export interface SemanticPoseDirection {
|
|
315
|
+
auId: number; label: string; available: boolean; availableSides?: Array<'left' | 'right' | 'center'>; hasBones: boolean; hasMorphs: boolean; morphStrength: number;
|
|
316
|
+
}
|
|
317
|
+
export interface SemanticPoseControl {
|
|
318
|
+
id: string; label: string; section: string; roles: string[]; bilateral: boolean;
|
|
319
|
+
boneNames: string[]; morphNames: string[];
|
|
320
|
+
positive: SemanticPoseDirection; negative?: SemanticPoseDirection;
|
|
321
|
+
}
|
|
322
|
+
export interface SemanticAnimation {
|
|
323
|
+
version: 1;
|
|
324
|
+
durationSeconds: number;
|
|
325
|
+
tracks: Array<{ controlId: string; direction: 'positive' | 'negative'; balance?: number; morphStrength?: number;
|
|
326
|
+
keyframes: Array<{ time: number; intensity: number }> }>;
|
|
327
|
+
}
|
|
328
|
+
export interface SemanticAnimationOptions extends Record<string, unknown> {
|
|
329
|
+
faceCurves?: Record<string, Array<{ time: number; intensity: number; inherit?: boolean }>>;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export interface Profile {
|
|
333
|
+
name?: string;
|
|
334
|
+
animalType?: string;
|
|
335
|
+
emoji?: string;
|
|
336
|
+
auToMorphs: Record<number, MorphTargetsBySide>;
|
|
337
|
+
auToBones: Record<number, BoneBinding[]>;
|
|
338
|
+
boneNodes: Record<string, string>;
|
|
339
|
+
bonePrefix?: string;
|
|
340
|
+
boneSuffix?: string;
|
|
341
|
+
morphPrefix?: string;
|
|
342
|
+
morphSuffix?: string;
|
|
343
|
+
suffixPattern?: string;
|
|
344
|
+
leftMorphSuffixes?: string[];
|
|
345
|
+
rightMorphSuffixes?: string[];
|
|
346
|
+
morphToMesh: Record<string, string[]>;
|
|
347
|
+
auFacePartToMeshCategory?: Record<string, string>;
|
|
348
|
+
mappingSections?: MappingEditorSection[];
|
|
349
|
+
visemeKeys: MorphTargetRef[];
|
|
350
|
+
visemeSystemId?: string;
|
|
351
|
+
visemeSlots?: VisemeSlot[];
|
|
352
|
+
visemeBindings?: Record<string, VisemeBinding>;
|
|
353
|
+
visemeMeshCategory?: string;
|
|
354
|
+
visemeJawAmounts?: number[];
|
|
355
|
+
/** Per-viseme tongue AU targets in canonical slot order. */
|
|
356
|
+
visemeTongueTargets?: VisemeTongueTarget[];
|
|
357
|
+
auMixDefaults?: Record<number, number>;
|
|
358
|
+
auInfo?: Record<string, AUInfo>;
|
|
359
|
+
eyeMeshNodes?: { LEFT: string; RIGHT: string };
|
|
360
|
+
compositeRotations?: CompositeRotation[];
|
|
361
|
+
meshes?: Record<string, MeshInfo>;
|
|
362
|
+
continuumPairs?: Record<number, {
|
|
363
|
+
pairId: number;
|
|
364
|
+
isNegative: boolean;
|
|
365
|
+
axis: BoneAxisKey;
|
|
366
|
+
node: string;
|
|
367
|
+
}>;
|
|
368
|
+
continuumLabels?: Record<string, string>;
|
|
369
|
+
annotationRegions?: Region[];
|
|
370
|
+
disabledRegions?: string[];
|
|
371
|
+
hairPhysics?: HairPhysicsProfileConfig;
|
|
372
|
+
gazeCalibration?: {
|
|
373
|
+
head?: { opticalAxis?: PolymerVector3 };
|
|
374
|
+
leftEye?: { opticalAxis?: PolymerVector3 };
|
|
375
|
+
rightEye?: { opticalAxis?: PolymerVector3 };
|
|
376
|
+
/** Authored model coordinate units per physical meter, before root scaling. */
|
|
377
|
+
modelUnitsPerMeter?: number;
|
|
378
|
+
};
|
|
379
|
+
humanoidCharacterization?: HumanoidCharacterization;
|
|
380
|
+
/** Authored overrides may patch individual fields; null removes a preset control. */
|
|
381
|
+
bodyControls?: Record<string, Partial<BodyControlDefinition> | null>;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export interface ProfileRuntimeConfig extends Partial<Profile> {
|
|
385
|
+
profilePresetId?: PresetType;
|
|
386
|
+
presetId?: PresetType;
|
|
387
|
+
baseProfileId?: PresetType;
|
|
388
|
+
auPresetType?: PresetType;
|
|
389
|
+
profile?: Partial<Profile>;
|
|
390
|
+
defaultRegion?: string;
|
|
391
|
+
regions?: Region[];
|
|
392
|
+
markerStyle?: MarkerStyle;
|
|
393
|
+
playIntroOnLoad?: boolean;
|
|
394
|
+
modelOffset?: { x?: number; y?: number; z?: number };
|
|
395
|
+
modelRotation?: { x?: number; y?: number; z?: number };
|
|
396
|
+
modelScale?: number;
|
|
397
|
+
modelGroundClearance?: number;
|
|
398
|
+
deletedBakedAnimationClips?: string[];
|
|
399
|
+
markerGroups?: MarkerGroup[];
|
|
400
|
+
lineDefaults?: LineConfig;
|
|
401
|
+
markerDefaults?: Partial<MarkerStyleOverrides>;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export interface CharacterProfile extends ProfileRuntimeConfig {
|
|
405
|
+
characterId?: string;
|
|
406
|
+
characterName?: string;
|
|
407
|
+
modelPath?: string;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export type CharacterConfig = CharacterProfile & {
|
|
411
|
+
characterId: string;
|
|
412
|
+
characterName: string;
|
|
413
|
+
modelPath: string;
|
|
414
|
+
regions: Region[];
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
export type LineStyle = 'solid' | 'dashed' | 'dotted';
|
|
418
|
+
export type LineCurve = 'straight' | 'bezier' | 'arc';
|
|
419
|
+
export type NamedDirection = 'radial' | 'camera' | 'up' | 'down' | 'left' | 'right' | 'forward' | 'backward';
|
|
420
|
+
export interface LineConfig { style?: LineStyle; curve?: LineCurve; arrowHead?: boolean; thickness?: number; length?: number; }
|
|
421
|
+
export interface MarkerStyleOverrides {
|
|
422
|
+
markerColor?: number;
|
|
423
|
+
markerRadius?: number;
|
|
424
|
+
lineColor?: number;
|
|
425
|
+
labelColor?: string;
|
|
426
|
+
labelBackground?: string;
|
|
427
|
+
labelFontSize?: number;
|
|
428
|
+
opacity?: number;
|
|
429
|
+
lineDirection?: NamedDirection | { x: number; y: number; z: number };
|
|
430
|
+
line?: LineConfig;
|
|
431
|
+
}
|
|
432
|
+
export type ExpandAnimation = 'outward' | 'staggered';
|
|
433
|
+
export interface ExpandedRegionState { regionName: string; isExpanded: boolean; children: string[]; }
|
|
434
|
+
export interface FallbackConfig { fallbackMarker?: string; clickBehavior?: 'fit-all' | 'rotate'; }
|
|
435
|
+
export interface MarkerGroup { groupId: string; regions: string[]; fallback?: FallbackConfig; }
|
|
436
|
+
export interface Region {
|
|
437
|
+
name: string;
|
|
438
|
+
bones?: string[];
|
|
439
|
+
meshes?: string[];
|
|
440
|
+
objects?: string[];
|
|
441
|
+
paddingFactor?: number;
|
|
442
|
+
cameraAngle?: number;
|
|
443
|
+
cameraOffset?: { x?: number; y?: number; z?: number };
|
|
444
|
+
parent?: string;
|
|
445
|
+
children?: string[];
|
|
446
|
+
expandAnimation?: ExpandAnimation;
|
|
447
|
+
style?: MarkerStyleOverrides;
|
|
448
|
+
groupId?: string;
|
|
449
|
+
isFallback?: boolean;
|
|
450
|
+
customPosition?: { x: number; y: number; z: number };
|
|
451
|
+
}
|
|
452
|
+
export type MarkerStyle = 'html' | '3d';
|
|
453
|
+
|
|
454
|
+
export interface HairColorAppearance { name: string; baseColor: string; emissive: string; emissiveIntensity: number; }
|
|
455
|
+
export interface HairAppearanceState { hairColor: HairColorAppearance; eyebrowColor: HairColorAppearance; showOutline: boolean; outlineColor: string; outlineOpacity: number; }
|
|
456
|
+
export interface HairPhysicsRuntimeConfig { enabled: boolean; [key: string]: any; }
|
|
457
|
+
export type HairPhysicsRuntimeConfigUpdate = Partial<HairPhysicsRuntimeConfig>;
|
|
458
|
+
export interface TransitionHandle { promise: Promise<void>; pause(): void; resume(): void; cancel(): void; }
|
|
459
|
+
|
|
460
|
+
export interface BoneAxisBindingUpdate {
|
|
461
|
+
channel?: RotationChannel;
|
|
462
|
+
positiveAuId?: number | null;
|
|
463
|
+
negativeAuId?: number | null;
|
|
464
|
+
positiveMaxDegrees?: number | null;
|
|
465
|
+
negativeMaxDegrees?: number | null;
|
|
466
|
+
positiveScale?: BoneAxisDirectionScale | null;
|
|
467
|
+
negativeScale?: BoneAxisDirectionScale | null;
|
|
468
|
+
positiveLeftScale?: BoneAxisDirectionScale | null;
|
|
469
|
+
positiveRightScale?: BoneAxisDirectionScale | null;
|
|
470
|
+
negativeLeftScale?: BoneAxisDirectionScale | null;
|
|
471
|
+
negativeRightScale?: BoneAxisDirectionScale | null;
|
|
472
|
+
}
|
|
473
|
+
export interface BoneAxisBindingState { axis: BoneAxisKey; channel: RotationChannel; nodeKey: string; positiveAuId: number | null; negativeAuId: number | null; positiveMaxDegrees: number | null; negativeMaxDegrees: number | null; positiveScale: BoneAxisDirectionScale | null; negativeScale: BoneAxisDirectionScale | null; }
|
|
474
|
+
export interface AUBoneBindingState { auId: number; boneName: string | null; nodeKey: string | null; axis: BoneAxisKey; direction: BoneAxisDirection; channel: RotationChannel | null; maxDegrees: number | null; oppositeAuId: number | null; oppositeMaxDegrees: number | null; hasBinding: boolean; hasMultipleBindings: boolean; }
|
|
475
|
+
export interface BilateralAxisDirectionScaleState { left: BoneAxisDirectionScale | null; right: BoneAxisDirectionScale | null; }
|
|
476
|
+
export interface BilateralAxisScopeBindingState { scope: BilateralBoneAxisScope; label: string; negativeAuId: number | null; positiveAuId: number | null; negativeMaxDegrees: number | null; positiveMaxDegrees: number | null; negativeScale: BilateralAxisDirectionScaleState; positiveScale: BilateralAxisDirectionScaleState; }
|
|
477
|
+
export interface BilateralAxisBindingState { axis: BoneAxisKey; familyLabel: string; leftBoneName: string; leftNodeKey: string; rightBoneName: string; rightNodeKey: string; selectedSide: 'left' | 'right'; shared: BilateralAxisScopeBindingState; left: BilateralAxisScopeBindingState; right: BilateralAxisScopeBindingState; }
|
|
478
|
+
export interface ChiralBoneNamePair { leftBoneName: string; rightBoneName: string; selectedSide: 'left' | 'right'; familyLabel: string; }
|
|
479
|
+
export interface CreatedBoneAxisAu { auId: number; profile: Profile; }
|
|
480
|
+
|
|
481
|
+
export interface BoneInfo { name: string; parent: string | null; children: string[]; worldPosition: { x: number; y: number; z: number }; depth: number; }
|
|
482
|
+
export interface TrackInfo { name: string; targetName: string; property: string; type: string; keyframeCount: number; valueRange?: { min: number[]; max: number[] }; }
|
|
483
|
+
export interface AnimationInfo { name: string; duration: number; tracks: TrackInfo[]; animatedBones: string[]; animatedMorphs: string[]; }
|
|
484
|
+
export interface ModelData { bones: BoneInfo[]; morphs: Array<{ name: string; meshName: string; index: number }>; meshes: Array<{ name: string; hasMorphTargets: boolean; morphCount: number }>; animations: AnimationInfo[]; boneNames: string[]; morphNames: string[]; meshNames: string[]; }
|
|
485
|
+
export interface MappingCorrection { type: 'bone' | 'morph' | 'viseme' | 'mesh'; source: string; target: string; confidence: number; reason: string; applied: boolean; auId?: number; key?: string; }
|
|
486
|
+
export interface ValidationResult { valid: boolean; score: number; missingMorphs: string[]; missingBones: string[]; foundMorphs: string[]; foundBones: string[]; unmappedMorphs: string[]; unmappedBones: string[]; missingMeshes: string[]; foundMeshes: string[]; unmappedMeshes: string[]; warnings: string[]; suggestedConfig?: Profile; corrections?: MappingCorrection[]; unresolved?: MappingCorrection[]; }
|
|
487
|
+
export interface ModelAnalysisReport { model: ModelData; validation?: ValidationResult; animations: { count: number; hasIdleCandidate: boolean; clips: unknown[] }; overallScore: number; summary: string; }
|
|
488
|
+
|
|
489
|
+
export interface AnnotationLaterality { leftSideX: 1 | -1; confidence: number; evidence: string[]; }
|
|
490
|
+
export interface BoneResolutionProfile { bonePrefix?: string; boneSuffix?: string; boneNodes?: Record<string, string>; suffixPattern?: string; }
|
|
491
|
+
export interface CameraRelativeGazeOffset { x: number; y: number; }
|
|
492
|
+
export interface CameraRelativeGazeOptions { yawWeight?: number; pitchWeight?: number; epsilon?: number; }
|
|
493
|
+
export interface MarkerEndpointSeparationOptions { starts: ArrayLike<number>; ends: ArrayLike<number>; modelCenter: { x: number; y: number; z: number }; modelHeight: number; }
|
|
494
|
+
|
|
495
|
+
export interface HumanoidSkeletonTemplateBone { readonly name: string; readonly parent: string | null; readonly translation: HumanoidSkeletonTemplateVec3; }
|
|
496
|
+
export interface HumanoidSkeletonTemplate { readonly id: string; readonly sourceCharacterId: string; readonly sourceAsset: string; readonly sourceSkinName: string; readonly bones: readonly HumanoidSkeletonTemplateBone[]; }
|
|
497
|
+
|
|
498
|
+
export interface CharacterModelLoadOptions { onProgress?: (progress: number) => void; castShadows?: boolean; dracoDecoderPath?: string; }
|
|
499
|
+
export interface CharacterModelLoadResult { model: Object3D; meshes: Mesh[]; animations: AnimationClip[]; gltf: GLTF | null; }
|
|
500
|
+
export interface CharacterModelTransform { modelOffset?: { x?: number; y?: number; z?: number }; modelRotation?: { x?: number; y?: number; z?: number }; modelScale?: number; modelGroundClearance?: number; }
|
|
501
|
+
export interface DefaultCharacterLightingSettings { envMapEnabled: boolean; environmentIntensity: number; environmentBlur: number; exposure: number; ambientIntensity: number; keyIntensity: number; fillIntensity: number; rimIntensity: number; shadowOpacity: number; }
|
|
502
|
+
export type DefaultCharacterLightingPresetId = 'cleanStudio' | 'softFill' | 'inspection' | 'contrast';
|
|
503
|
+
export type CharacterSceneTypeId = 'studio' | 'showcase' | 'inspection' | 'void';
|
|
504
|
+
export interface CharacterSceneTypeDefinition { id: CharacterSceneTypeId; label: string; description: string; background: number | null; lightingPreset: DefaultCharacterLightingPresetId; shadowPlane: boolean; }
|
|
505
|
+
export interface DefaultCharacterLightingController { getSettings(): DefaultCharacterLightingSettings; getEnvironmentTexture(): Texture | null; setSettings(patch: Partial<DefaultCharacterLightingSettings>): DefaultCharacterLightingSettings; setPreset(id: DefaultCharacterLightingPresetId): DefaultCharacterLightingSettings; subscribe(listener: (settings: DefaultCharacterLightingSettings) => void): () => void; dispose(): void; }
|
|
506
|
+
export interface DefaultCharacterSceneOptions { type?: CharacterSceneTypeId; cameraFov?: number; pixelRatioCap?: number; shadows?: boolean; shadowPlane?: boolean; background?: ColorRepresentation | null; lighting?: Partial<DefaultCharacterLightingSettings>; lightingPreset?: DefaultCharacterLightingPresetId; manageResize?: boolean; }
|
|
507
|
+
export interface DefaultCharacterScene { container: HTMLElement; scene: Scene; renderer: WebGLRenderer; camera: PerspectiveCamera; lighting: DefaultCharacterLightingController; shadowPlane: Mesh | null; sceneType: CharacterSceneTypeId; ownsScene: true; resize(): void; dispose(): void; }
|
|
508
|
+
export interface CharacterHostCharacterOptions extends CharacterModelTransform { modelUrl: string; presetType?: PresetType; profile?: Profile; }
|
|
509
|
+
export interface CharacterHostExternalScene { scene: Scene; renderer: CharacterSceneRenderer; backend?: CharacterSceneBackend; rendering?: CharacterSceneRenderingController; camera: Camera; mountCanvas?: boolean; manageResize?: boolean; }
|
|
510
|
+
/** Cancellation applies only until creation resolves; dispose the resolved host explicitly. */
|
|
511
|
+
export interface CharacterHostOptions { signal?: AbortSignal; container: HTMLElement; character: CharacterHostCharacterOptions; embody?: RustEmbodyHostConfig; scene?: Omit<DefaultCharacterSceneAsyncOptions, 'signal'>; external?: CharacterHostExternalScene; loader?: CharacterModelLoadOptions; autoStart?: boolean; renderLoop?: boolean; autoFrame?: boolean; }
|
|
512
|
+
export interface CharacterHost { engine: Embody; scene: Scene; readonly renderer: CharacterSceneRenderer; readonly backend: CharacterSceneBackend | null; readonly rendering: CharacterSceneRenderingController | null; camera: Camera | PerspectiveCamera; model: Object3D; meshes: Mesh[]; animations: AnimationClip[]; lighting: DefaultCharacterLightingController | null; ownsScene: boolean; container: HTMLElement; setCharacter(character: CharacterHostCharacterOptions, loader?: CharacterModelLoadOptions): Promise<void>; resize(): void; dispose(): Promise<void>; }
|
|
513
|
+
|
|
514
|
+
export interface CharacterRegistry { characters: CharacterConfig[]; defaultCharacter?: string; }
|
|
515
|
+
export type AnimationSource = 'baked' | 'clip' | 'snippet';
|
|
516
|
+
export type AnimationBlendMode = 'replace' | 'additive';
|
|
517
|
+
export type BakedClipChannel = 'face' | 'body' | 'scene';
|
|
518
|
+
export interface AnimationClipInfo { name: string; duration: number; trackCount: number; source?: AnimationSource; channels?: BakedClipChannelInfo[]; }
|
|
519
|
+
export interface ThreeMaterialConfig extends MeshMaterialSettings {}
|
|
520
|
+
export interface ThreeResolvedMaterialConfig { renderOrder: number; transparent: boolean; opacity: number; depthWrite: boolean; depthTest: boolean; blending: BlendingMode; }
|
|
12
521
|
|
|
13
522
|
/** Direct Embody Wasm core accessors (via @lovelace_lol/embody/wasm). */
|
|
14
523
|
export declare function initEmbodyCore(): Promise<EmbodyCoreWasmModule>;
|
|
@@ -94,11 +603,14 @@ export interface WasmRuntimeCore {
|
|
|
94
603
|
set_au(id: number, value: number, balance: number): void;
|
|
95
604
|
set_au_signed(id: number, value: number, balance: number): void;
|
|
96
605
|
get_au(id: number): number;
|
|
606
|
+
get_au_balance(id: number): number;
|
|
97
607
|
set_continuum(negAu: number, posAu: number, value: number, balance: number): void;
|
|
98
608
|
get_continuum(negAu: number, posAu: number): number;
|
|
99
609
|
set_au_mix_weight(id: number, weight: number): void;
|
|
100
610
|
set_viseme(index: number, value: number): void;
|
|
101
611
|
set_viseme_jaw_scale(index: number, jawScale: number): void;
|
|
612
|
+
get_viseme(index: number): number;
|
|
613
|
+
get_viseme_jaw_scale(index: number): number;
|
|
102
614
|
set_viseme_slot_count(count: number): void;
|
|
103
615
|
transition_au(id: number, to: number, durationMs: number, balance: number): void;
|
|
104
616
|
transition_viseme(index: number, to: number, durationMs: number, jawScale: number): void;
|
|
@@ -142,6 +654,19 @@ export interface EmbodyCoreWasmModule {
|
|
|
142
654
|
manualScale: number,
|
|
143
655
|
manualTranslation: Float32Array
|
|
144
656
|
): Float32Array;
|
|
657
|
+
solve_profile_screen_space_gaze(
|
|
658
|
+
profileJson: string,
|
|
659
|
+
screenTarget: Float32Array,
|
|
660
|
+
cameraPosition: Float32Array,
|
|
661
|
+
cameraQuaternion: Float32Array,
|
|
662
|
+
gazeOrigin: Float32Array,
|
|
663
|
+
modelQuaternion: Float32Array,
|
|
664
|
+
verticalFovDegrees: number,
|
|
665
|
+
aspect: number,
|
|
666
|
+
eyesEnabled: boolean,
|
|
667
|
+
headEnabled: boolean,
|
|
668
|
+
headFollowFraction: number
|
|
669
|
+
): Float32Array;
|
|
145
670
|
default_hair_physics_config_values(): Float32Array;
|
|
146
671
|
list_presets(): string[];
|
|
147
672
|
has_preset(presetId: string): boolean;
|
|
@@ -161,13 +686,18 @@ export type RustEmbodyHostConfig =
|
|
|
161
686
|
presetType?: string;
|
|
162
687
|
profile?: Partial<Profile>;
|
|
163
688
|
meshes?: unknown[];
|
|
689
|
+
/** Reference for the first model bound to this host. */
|
|
690
|
+
referencePose?: ThreeModelReferencePose;
|
|
164
691
|
}
|
|
165
692
|
| {
|
|
166
693
|
profileMode: 'profile';
|
|
167
|
-
profile
|
|
694
|
+
/** Exact profile; an empty object renders an unmapped model for authoring. */
|
|
695
|
+
profile: Partial<Profile>;
|
|
168
696
|
presetId?: never;
|
|
169
697
|
presetType?: never;
|
|
170
698
|
meshes?: unknown[];
|
|
699
|
+
/** Reference for the first model bound to this host. */
|
|
700
|
+
referencePose?: ThreeModelReferencePose;
|
|
171
701
|
};
|
|
172
702
|
|
|
173
703
|
/**
|
|
@@ -181,8 +711,12 @@ export interface PolymerCharacterRuntime {
|
|
|
181
711
|
readonly meshes: unknown[];
|
|
182
712
|
readonly meshByName: Map<string, unknown>;
|
|
183
713
|
readonly bones: Record<string, unknown>;
|
|
184
|
-
|
|
714
|
+
/** First bind captures the model reference unless an explicit capture is supplied. */
|
|
715
|
+
onReady(options: { model: unknown; meshes?: unknown[]; animations?: unknown[]; referencePose?: ThreeModelReferencePose }): void;
|
|
716
|
+
/** Rebind using the original reference; incompatible hierarchy edits throw. */
|
|
185
717
|
bindModel(meshes?: unknown[]): void;
|
|
718
|
+
/** Explicitly include appended nodes without recapturing existing posed nodes. */
|
|
719
|
+
extendReferencePose(): ThreeModelReferencePose;
|
|
186
720
|
setProfile(profile: Profile): void;
|
|
187
721
|
getProfile(): Profile;
|
|
188
722
|
getProfileMode(): RustEmbodyProfileMode;
|
|
@@ -190,24 +724,44 @@ export interface PolymerCharacterRuntime {
|
|
|
190
724
|
supportsPreset(presetId?: string): boolean;
|
|
191
725
|
setAU(id: number, value: number, balance?: number): void;
|
|
192
726
|
getAU(id: number): number;
|
|
727
|
+
/** Current procedural left/right balance (-1..1), or zero after clear. */
|
|
728
|
+
getAUBalance(id: number): number;
|
|
729
|
+
/** Resolve body controls from the configured Rust profile/model; no scene traversal. */
|
|
730
|
+
getBodyControls(): BodyControlDescriptor[];
|
|
731
|
+
getSemanticPoseCatalog(): SemanticPoseControl[];
|
|
732
|
+
captureSemanticPose(): SemanticPose;
|
|
733
|
+
validateSemanticPose(pose: SemanticPose): SemanticPose;
|
|
734
|
+
applySemanticPose(pose: SemanticPose): void;
|
|
735
|
+
validateSemanticAnimation(animation: SemanticAnimation, options?: SemanticAnimationOptions): void;
|
|
736
|
+
semanticAnimationToClip(name: string, animation: SemanticAnimation, options?: SemanticAnimationOptions): AnimationPlaybackHandle;
|
|
737
|
+
/** Reset configured body actions atomically and apply one procedural frame. */
|
|
738
|
+
resetBodyControls(): void;
|
|
193
739
|
setContinuum(negAU: number, posAU: number, value: number, balance?: number): void;
|
|
194
740
|
getContinuum(negAU: number, posAU: number): number;
|
|
195
|
-
|
|
741
|
+
/** Mixer-timed live control; defaults to 200 ms. getAU reports its destination immediately. */
|
|
742
|
+
transitionAU(id: number, to: number, durationMs?: number, balance?: number): TransitionHandle;
|
|
196
743
|
setViseme(index: number, value: number, jawScale?: number): void;
|
|
744
|
+
/** Canonical direct viseme value; unset, cleared or out-of-range slots return 0. Does not sample mixer output. */
|
|
745
|
+
getViseme(index: number): number;
|
|
746
|
+
/** Canonical direct jaw scale; unset, cleared or out-of-range slots return 1. */
|
|
747
|
+
getVisemeJawScale(index: number): number;
|
|
197
748
|
setVisemeById(slotId: string, value: number, jawScale?: number): void;
|
|
198
|
-
|
|
199
|
-
|
|
749
|
+
/** Mixer-timed live control; defaults to 80 ms. getViseme reports the sampled direct value. */
|
|
750
|
+
transitionViseme(index: number, to: number, durationMs?: number, jawScale?: number): TransitionHandle;
|
|
751
|
+
transitionVisemeById(slotId: string, to: number, durationMs?: number, jawScale?: number): TransitionHandle;
|
|
200
752
|
setAUMixWeight(id: number, weight: number): void;
|
|
201
753
|
getAUMixWeight(id: number): number;
|
|
202
754
|
hasLeftRightBones(id: number): boolean;
|
|
203
755
|
setMorph(key: string | number, value: number, meshNames?: string[]): void;
|
|
204
756
|
setMorphOnMeshes(meshNames: string[], key: string | number, value: number): void;
|
|
757
|
+
/** Relinquish a direct morph override so current AU/viseme/clip output can resume. */
|
|
758
|
+
releaseMorph(key: string | number, meshNames?: string[]): void;
|
|
205
759
|
transitionMorph(
|
|
206
760
|
key: string | number,
|
|
207
761
|
value: number,
|
|
208
762
|
durationMs?: number,
|
|
209
763
|
meshNames?: string[]
|
|
210
|
-
):
|
|
764
|
+
): TransitionHandle;
|
|
211
765
|
getMorphTargets(): Record<string, string[]>;
|
|
212
766
|
getMorphTargetIndices(): Record<string, Array<{ index: number; name: string }>>;
|
|
213
767
|
getHairMorphTargets(meshName: string): string[];
|
|
@@ -216,10 +770,10 @@ export interface PolymerCharacterRuntime {
|
|
|
216
770
|
getBones(): Record<string, unknown>;
|
|
217
771
|
setMeshVisible(meshName: string, visible: boolean): void;
|
|
218
772
|
highlightMesh(meshName: string | null, color?: number, intensity?: number): void;
|
|
219
|
-
getMeshMaterialConfig(meshName: string):
|
|
773
|
+
getMeshMaterialConfig(meshName: string): ThreeResolvedMaterialConfig | null;
|
|
220
774
|
setMeshMaterialConfig(
|
|
221
775
|
meshName: string,
|
|
222
|
-
config:
|
|
776
|
+
config: ThreeMaterialConfig
|
|
223
777
|
): void;
|
|
224
778
|
registerHairObjects(
|
|
225
779
|
objects: Object3D[]
|
|
@@ -240,28 +794,42 @@ export interface PolymerCharacterRuntime {
|
|
|
240
794
|
validateHairMorphTargets(): string[];
|
|
241
795
|
updateHairPhysics(dtSeconds: number): void;
|
|
242
796
|
loadAnimationClips(clips: unknown[]): void;
|
|
243
|
-
|
|
797
|
+
/**
|
|
798
|
+
* Register additional baked sources on a bound model without starting clips
|
|
799
|
+
* or interrupting playback. Identical sources are ignored; a replacement
|
|
800
|
+
* under the same name takes effect on the next play. Sources survive rebinds.
|
|
801
|
+
*/
|
|
802
|
+
registerAnimationClips(clips: unknown[]): void;
|
|
803
|
+
/** Remove a source and its active action, including the source retained for rebinding. */
|
|
804
|
+
removeAnimationClip(clipName: string): boolean;
|
|
805
|
+
getAnimationClips(): AnimationClipInfo[];
|
|
244
806
|
playAnimation(
|
|
245
807
|
clipName: string,
|
|
246
|
-
options?:
|
|
247
|
-
):
|
|
808
|
+
options?: Record<string, unknown>
|
|
809
|
+
): AnimationPlaybackHandle;
|
|
248
810
|
stopAnimation(clipName: string): void;
|
|
249
811
|
stopAllAnimations(): void;
|
|
250
812
|
playTypedSnippet(
|
|
251
|
-
snippet:
|
|
252
|
-
options?:
|
|
253
|
-
):
|
|
813
|
+
snippet: Record<string, unknown>,
|
|
814
|
+
options?: Record<string, unknown>
|
|
815
|
+
): AnimationPlaybackHandle;
|
|
254
816
|
buildTypedClip(
|
|
255
817
|
clipName: string,
|
|
256
|
-
channels:
|
|
257
|
-
options?:
|
|
258
|
-
):
|
|
818
|
+
channels: unknown[],
|
|
819
|
+
options?: Record<string, unknown>
|
|
820
|
+
): AnimationPlaybackHandle;
|
|
259
821
|
buildClip(
|
|
260
822
|
clipName: string,
|
|
261
|
-
curves:
|
|
262
|
-
options?:
|
|
263
|
-
):
|
|
823
|
+
curves: Record<string, unknown>,
|
|
824
|
+
options?: Record<string, unknown>
|
|
825
|
+
): AnimationPlaybackHandle;
|
|
264
826
|
cleanupSnippet(name: string): void;
|
|
827
|
+
/** Read-only seed for gaze motor controls in the current evaluated pose. */
|
|
828
|
+
getGazeControlState(options?: { worldTarget?: PolymerVector3; headIntensity?: number; eyeIntensity?: number }): GazeControlState | null;
|
|
829
|
+
/** Last evaluated optical-ray diagnostics; null without active focus controls. */
|
|
830
|
+
getGazeFocusDiagnostics(): GazeFocusDiagnostics | null;
|
|
831
|
+
/** Fresh immutable copy of the last positive-dt pose update; polling does not renew its stamp. */
|
|
832
|
+
getGazeObservation(): GazeObservation | null;
|
|
265
833
|
update(dtSeconds: number): void;
|
|
266
834
|
start(): void;
|
|
267
835
|
stop(): void;
|
|
@@ -270,6 +838,24 @@ export interface PolymerCharacterRuntime {
|
|
|
270
838
|
dispose(): void;
|
|
271
839
|
}
|
|
272
840
|
|
|
841
|
+
export interface AnimationPlaybackHandle extends TransitionHandle {
|
|
842
|
+
name: string;
|
|
843
|
+
actionId?: string;
|
|
844
|
+
play(): AnimationPlaybackHandle;
|
|
845
|
+
stop(): AnimationPlaybackHandle;
|
|
846
|
+
setWeight(value: number): AnimationPlaybackHandle;
|
|
847
|
+
setSpeed(value: number): AnimationPlaybackHandle;
|
|
848
|
+
setTime(value: number): AnimationPlaybackHandle;
|
|
849
|
+
subscribe(listener: ((event: unknown) => void) | { next(event: unknown): void }): () => void;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
export interface EmbodyRuntime extends PolymerCharacterRuntime {}
|
|
853
|
+
export declare class Embody {
|
|
854
|
+
constructor(config?: RustEmbodyHostConfig);
|
|
855
|
+
static create(config?: RustEmbodyHostConfig): Promise<Embody>;
|
|
856
|
+
[key: string]: any;
|
|
857
|
+
}
|
|
858
|
+
|
|
273
859
|
export declare function createRustEmbodyHost(
|
|
274
860
|
model: unknown,
|
|
275
861
|
config?: RustEmbodyHostConfig
|
|
@@ -281,172 +867,102 @@ export declare function createRustEmbodyHostUnbound(
|
|
|
281
867
|
|
|
282
868
|
export declare function supportsRustEmbodyPreset(presetId?: string): boolean;
|
|
283
869
|
|
|
284
|
-
export
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
export
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
CharacterModelTransform,
|
|
381
|
-
CharacterSceneTypeDefinition,
|
|
382
|
-
CharacterSceneTypeId,
|
|
383
|
-
DefaultCharacterLightingController,
|
|
384
|
-
DefaultCharacterLightingPresetId,
|
|
385
|
-
DefaultCharacterLightingSettings,
|
|
386
|
-
DefaultCharacterScene,
|
|
387
|
-
DefaultCharacterSceneOptions,
|
|
388
|
-
HairAppearanceState,
|
|
389
|
-
HairColorAppearance,
|
|
390
|
-
HairPhysicsRuntimeConfig,
|
|
391
|
-
HairPhysicsRuntimeConfigUpdate,
|
|
392
|
-
MarkerEndpointSeparationOptions,
|
|
393
|
-
} from '@lovelace_lol/embody';
|
|
394
|
-
|
|
395
|
-
export type {
|
|
396
|
-
AUBoneBindingState,
|
|
397
|
-
AUInfo,
|
|
398
|
-
AnimationClipInfo,
|
|
399
|
-
AnimationInfo,
|
|
400
|
-
AnnotationLaterality,
|
|
401
|
-
BilateralAxisBindingState,
|
|
402
|
-
BilateralAxisDirectionScaleState,
|
|
403
|
-
BilateralAxisScopeBindingState,
|
|
404
|
-
BilateralBoneAxisScope,
|
|
405
|
-
BoneAxisBindingState,
|
|
406
|
-
BoneAxisBindingUpdate,
|
|
407
|
-
BoneAxisDirection,
|
|
408
|
-
BoneAxisDirectionScale,
|
|
409
|
-
BoneAxisKey,
|
|
410
|
-
BoneBinding,
|
|
411
|
-
BoneControlFamily,
|
|
412
|
-
BoneControlScope,
|
|
413
|
-
BoneInfo,
|
|
414
|
-
CameraRelativeGazeOffset,
|
|
415
|
-
CameraRelativeGazeOptions,
|
|
416
|
-
CharacterConfig,
|
|
417
|
-
CharacterRegistry,
|
|
418
|
-
ChiralBoneNamePair,
|
|
419
|
-
CompositeRotation,
|
|
420
|
-
CreatedBoneAxisAu,
|
|
421
|
-
ExpandAnimation,
|
|
422
|
-
ExpandedRegionState,
|
|
423
|
-
FallbackConfig,
|
|
424
|
-
LineConfig,
|
|
425
|
-
LineCurve,
|
|
426
|
-
LineStyle,
|
|
427
|
-
EmbodyRuntime,
|
|
428
|
-
MarkerGroup,
|
|
429
|
-
MarkerStyle,
|
|
430
|
-
MarkerStyleOverrides,
|
|
431
|
-
MeshInfo,
|
|
432
|
-
ModelAnalysisReport,
|
|
433
|
-
ModelData,
|
|
434
|
-
MorphTargetsBySide,
|
|
435
|
-
NamedDirection,
|
|
436
|
-
PresetType,
|
|
437
|
-
Profile,
|
|
438
|
-
Region,
|
|
439
|
-
RotationAxis,
|
|
440
|
-
RotationChannel,
|
|
441
|
-
TrackInfo,
|
|
442
|
-
TransitionHandle,
|
|
443
|
-
ValidationResult,
|
|
444
|
-
VisemeSlot,
|
|
445
|
-
HumanoidSkeletonTemplate,
|
|
446
|
-
HumanoidSkeletonTemplateBone,
|
|
447
|
-
HumanoidSkeletonTemplateBounds,
|
|
448
|
-
HumanoidSkeletonTemplateVec3,
|
|
449
|
-
} from '@lovelace_lol/embody';
|
|
870
|
+
export declare const BLENDING_MODES: Record<BlendingMode, number>;
|
|
871
|
+
export declare const THREE_BLENDING_MODES: Record<BlendingMode, number>;
|
|
872
|
+
export declare function collectMorphMeshes(root: Object3D): Mesh[];
|
|
873
|
+
export declare function analyzeModel(options: {
|
|
874
|
+
source: { type: 'gltf'; gltf: GLTF } | { type: 'runtime'; model: Object3D; meshes: Mesh[]; animations: AnimationClip[] };
|
|
875
|
+
preset?: Profile;
|
|
876
|
+
suggestCorrections?: boolean;
|
|
877
|
+
}): Promise<ModelAnalysisReport>;
|
|
878
|
+
export declare function extractModelData(model: Object3D, meshes?: Mesh[], animations?: AnimationClip[]): ModelData;
|
|
879
|
+
export declare function getPreset(presetId: PresetType): Profile;
|
|
880
|
+
export declare function validateMappings(meshes: unknown[], skeleton: unknown, profile: Profile, options?: Record<string, unknown>): ValidationResult;
|
|
881
|
+
export declare function validateHumanoidCharacterization(model: Object3D, profile: Profile): HumanoidCharacterizationResolution;
|
|
882
|
+
export declare function extendCharacterConfigWithPreset(config: CharacterConfig): CharacterConfig;
|
|
883
|
+
export declare function extractProfileOverrides(config: CharacterConfig): Partial<Profile>;
|
|
884
|
+
export declare function mergeCharacterRegionsByName(base?: Region[], override?: Region[]): Region[];
|
|
885
|
+
export declare function applyAUBoneBindingUpdate(profile: Profile, auId: number, update: { boneName: string | null; axis: BoneAxisKey; direction: BoneAxisDirection; maxDegrees: number | null }): Profile;
|
|
886
|
+
export declare function applyBilateralAxisBindingUpdate(profile: Profile, boneName: string, axis: BoneAxisKey, scope: BilateralBoneAxisScope, update: BoneAxisBindingUpdate): Profile;
|
|
887
|
+
export declare function applyBoneAxisBindingUpdate(profile: Profile, boneName: string, axis: BoneAxisKey, update: BoneAxisBindingUpdate): Profile;
|
|
888
|
+
export declare function buildBoneAuOptions(profile: Profile): Array<{ value: string; label: string; detail?: string }>;
|
|
889
|
+
export declare function classifyAuAsJointControl(profile: Profile, auId: number, options?: { boneName?: string | null; nodeKey?: string | null }): Profile;
|
|
890
|
+
export declare function createBilateralBoneAxisAu(profile: Profile, boneName: string, axis: BoneAxisKey, scope: BilateralBoneAxisScope, direction: BoneAxisDirection, options?: { name?: string }): CreatedBoneAxisAu;
|
|
891
|
+
export declare function createBoneAxisAu(profile: Profile, boneName: string, axis: BoneAxisKey, direction: BoneAxisDirection, options?: { name?: string }): CreatedBoneAxisAu;
|
|
892
|
+
export declare const DEFAULT_AXIS_TO_CHANNEL: Record<BoneAxisKey, RotationChannel>;
|
|
893
|
+
export declare const DEFAULT_BONE_MAX_DEGREES: number;
|
|
894
|
+
export declare function ensureBilateralBoneNodeKeys(profile: Profile, leftBoneName: string, rightBoneName: string): Profile;
|
|
895
|
+
export declare function ensureBoneNodeKey(profile: Profile, boneName: string): { nodeKey: string; boneNodes: Record<string, string> };
|
|
896
|
+
export declare function findNodeKeyForBone(boneName: string, profile: Profile | null): string | null;
|
|
897
|
+
export declare function formatAxisDirectionLabel(axis: BoneAxisKey, direction: BoneAxisDirection): string;
|
|
898
|
+
export declare function formatAxisLabel(axis: BoneAxisKey): string;
|
|
899
|
+
export declare function getAUBoneBindingState(profile: Profile, auId: number): AUBoneBindingState;
|
|
900
|
+
export declare function getAxisFromChannel(channel?: string): BoneAxisKey | null;
|
|
901
|
+
export declare function getBilateralAxisBindingState(profile: Profile, boneName: string, axis: BoneAxisKey): BilateralAxisBindingState | null;
|
|
902
|
+
export declare function getBoneAxisBindingState(profile: Profile, boneName: string, axis: BoneAxisKey): BoneAxisBindingState | null;
|
|
903
|
+
export declare function inferChiralBoneNamePair(boneNames: string[], selectedBoneName: string): ChiralBoneNamePair | null;
|
|
904
|
+
export declare function inferEyeControlFamily(binding: Pick<BoneAxisBindingState, 'nodeKey' | 'axis'>): BoneControlFamily | null;
|
|
905
|
+
export declare function inferEyeControlScope(profile: Pick<Profile, 'auToBones'>, binding: Pick<BoneAxisBindingState, 'nodeKey' | 'negativeAuId' | 'positiveAuId'>): BoneControlScope | null;
|
|
906
|
+
export declare function isJointControlAuInfo(info?: Pick<AUInfo, 'facePart'> | null): boolean;
|
|
907
|
+
export declare function isMaxDegreesOnlyAxisBindingUpdate(update: BoneAxisBindingUpdate): boolean;
|
|
908
|
+
export declare const JOINT_CONTROL_SECTION: string;
|
|
909
|
+
export declare function resolveBoneAxisChannel(profile: Profile, boneName: string, axis: BoneAxisKey): RotationChannel;
|
|
910
|
+
export declare function resolveBoneNameForNodeKey(profile: Profile, nodeKey: string): string | null;
|
|
911
|
+
export declare function resolveContinuumDisplayLabel(profile: Pick<Profile, 'continuumPairs' | 'continuumLabels' | 'auInfo' | 'boneNodes' | 'bonePrefix' | 'boneSuffix'>, negativeAuId: number, positiveAuId: number): string;
|
|
912
|
+
export declare function stripConfiguredBoneAffixes(profile: { bonePrefix?: string; boneSuffix?: string } | null | undefined, boneName: string): string;
|
|
913
|
+
export declare function computeCameraRelativeGazeOffset(model: Object3D | null, cameraPosition: { x: number; y: number; z: number }, targetPosition: { x: number; y: number; z: number }, options?: CameraRelativeGazeOptions): CameraRelativeGazeOffset;
|
|
914
|
+
export declare function solveScreenSpaceGaze(options: ScreenSpaceGazeOptions): ScreenSpaceGazeSolution;
|
|
915
|
+
export declare function createEmbodyGazeRuntime(
|
|
916
|
+
profileProvider: Profile | (() => Profile),
|
|
917
|
+
host?: Pick<PolymerCharacterRuntime, 'getGazeControlState'>
|
|
918
|
+
): EmbodyGazeRuntime;
|
|
919
|
+
export declare function fuzzyNameMatch(objectName: string, targetName: string, suffixPattern?: string): boolean;
|
|
920
|
+
export declare function getMeshNamesForAUProfile(profile: Profile, auId: number): string[];
|
|
921
|
+
export declare function hasLeftRightMorphs(auId: number): boolean;
|
|
922
|
+
export declare function hasLeftRightMorphs(profile: Profile, auId: number): boolean;
|
|
923
|
+
export declare function isMixedAU(auId: number): boolean;
|
|
924
|
+
export declare function isMixedAU(profile: Profile, auId: number): boolean;
|
|
925
|
+
export declare function resolveBoneNames(names: string[] | undefined, profile?: BoneResolutionProfile): string[];
|
|
926
|
+
/** All 55 VRM 1.0 roles, including required flags and optional-parent rules. */
|
|
927
|
+
export declare function getHumanoidSpecification(): HumanoidSpecification;
|
|
928
|
+
/** Assign an actual model bone or clear a role; returns a new authoritative profile. */
|
|
929
|
+
export declare function setHumanoidRoleBinding(profile: Profile, role: VRMHumanoidRole, boneName: string | null): Profile;
|
|
930
|
+
/** Replace one action side's targets, preserving other actions sharing those morphs. */
|
|
931
|
+
export declare function setAUMorphTargets(profile: Profile, auId: number, side: 'left' | 'right' | 'center', targets: Array<string | number>): Profile;
|
|
932
|
+
export declare function resolveHumanoidCharacterization(profile: Profile): HumanoidCharacterizationResolution;
|
|
933
|
+
/** With a model, reports missing bone/morph targets against the actual scene. */
|
|
934
|
+
export declare function getBodyControls(profile: Profile, model?: Object3D): BodyControlDescriptor[];
|
|
935
|
+
export declare function resolveCharacterGazeOrigin(model: Object3D, profile?: Profile | null): Vector3 | null;
|
|
936
|
+
export declare const CC4_BONES: Record<string, string>;
|
|
937
|
+
export declare const VISEME_KEYS: string[];
|
|
938
|
+
export declare const HAIR_COLOR_PRESETS: Record<string, HairColorAppearance>;
|
|
939
|
+
export declare const DEFAULT_HAIR_COLOR_APPEARANCE: HairColorAppearance;
|
|
940
|
+
export declare function normalizeHairColorAppearance(value: HairColorAppearance | string, fallback?: HairColorAppearance): HairColorAppearance;
|
|
941
|
+
export declare const HUMANOID_SKELETON_TEMPLATES: readonly HumanoidSkeletonTemplate[];
|
|
942
|
+
export declare const CC4_HUMANOID_SKELETON_TEMPLATE: HumanoidSkeletonTemplate;
|
|
943
|
+
export declare function getHumanoidSkeletonTemplate(id: string): HumanoidSkeletonTemplate | null;
|
|
944
|
+
export declare function getHumanoidSkeletonTemplateBoneNames(template?: HumanoidSkeletonTemplate): string[];
|
|
945
|
+
export declare function createValidationSkeletonFromHumanoidTemplate(template?: HumanoidSkeletonTemplate): { bones: Array<{ name: string }> };
|
|
946
|
+
export declare function computeHumanoidSkeletonTemplateRestBounds(template: HumanoidSkeletonTemplate): HumanoidSkeletonTemplateBounds;
|
|
947
|
+
export declare function extractHumanoidSkeletonTemplateFromModel(model: Object3D, options: { id: string; sourceCharacterId: string; sourceAsset?: string; sourceSkinName?: string }): HumanoidSkeletonTemplate;
|
|
948
|
+
export declare function createCharacterHost(options: CharacterHostOptions): Promise<CharacterHost>;
|
|
949
|
+
export declare function createDefaultCharacterScene(container: HTMLElement, options?: DefaultCharacterSceneOptions): DefaultCharacterScene;
|
|
950
|
+
export declare function createDefaultCharacterSceneAsync(container: HTMLElement, options?: DefaultCharacterSceneAsyncOptions): Promise<ReadyDefaultCharacterScene>;
|
|
951
|
+
export declare function createDefaultCharacterSceneRuntime(container: HTMLElement, options?: DefaultCharacterSceneRuntimeOptions): DefaultCharacterSceneRuntime;
|
|
952
|
+
export declare function createDefaultCharacterLighting(scene: Scene, renderer: WebGLRenderer, settings?: Partial<DefaultCharacterLightingSettings>): DefaultCharacterLightingController;
|
|
953
|
+
export declare function createShadowPlane(scene: Scene, options?: { size?: number; opacity?: number; yPosition?: number }): Mesh;
|
|
954
|
+
export declare function loadCharacterModel(url: string, options?: CharacterModelLoadOptions): Promise<CharacterModelLoadResult>;
|
|
955
|
+
export declare function parseCharacterModel(data: ArrayBuffer, resourcePath?: string, options?: CharacterModelLoadOptions): Promise<CharacterModelLoadResult>;
|
|
956
|
+
export declare function applyCharacterModelTransform(model: Object3D, value?: CharacterModelTransform): void;
|
|
957
|
+
export declare function disposeCharacterModel(scene: Scene | null, model: Object3D): void;
|
|
958
|
+
export declare const DEFAULT_CHARACTER_LIGHTING_PRESET_ID: DefaultCharacterLightingPresetId;
|
|
959
|
+
export declare const DEFAULT_CHARACTER_LIGHTING_PRESET_IDS: readonly DefaultCharacterLightingPresetId[];
|
|
960
|
+
export declare const DEFAULT_CHARACTER_LIGHTING_PRESETS: Record<DefaultCharacterLightingPresetId, { id: DefaultCharacterLightingPresetId; label: string; settings: DefaultCharacterLightingSettings }>;
|
|
961
|
+
export declare const DEFAULT_CHARACTER_LIGHTING_SETTINGS: DefaultCharacterLightingSettings;
|
|
962
|
+
export declare function normalizeDefaultCharacterLightingSettings(value: unknown): DefaultCharacterLightingSettings | null;
|
|
963
|
+
export declare const CHARACTER_SCENE_TYPES: Record<CharacterSceneTypeId, CharacterSceneTypeDefinition>;
|
|
964
|
+
export declare const CHARACTER_SCENE_TYPE_IDS: readonly CharacterSceneTypeId[];
|
|
965
|
+
export declare const DEFAULT_CHARACTER_SCENE_TYPE_ID: CharacterSceneTypeId;
|
|
450
966
|
|
|
451
967
|
export interface BlinkState {
|
|
452
968
|
agency: 'blink';
|
|
@@ -474,21 +990,176 @@ export interface GazeTarget {
|
|
|
474
990
|
z?: number;
|
|
475
991
|
}
|
|
476
992
|
|
|
993
|
+
export interface GazeControlState {
|
|
994
|
+
headSeedLimited?: boolean;
|
|
995
|
+
eyeSeedLimited?: boolean;
|
|
996
|
+
target?: Required<GazeTarget>;
|
|
997
|
+
eyeTarget: Required<GazeTarget>;
|
|
998
|
+
headTarget: Required<GazeTarget>;
|
|
999
|
+
headRoll: number;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
export interface GazeFocusRequest {
|
|
1003
|
+
worldTarget: PolymerVector3;
|
|
1004
|
+
target: Required<GazeTarget>;
|
|
1005
|
+
headTarget?: Required<GazeTarget>;
|
|
1006
|
+
eyesEnabled: boolean;
|
|
1007
|
+
headEnabled: boolean;
|
|
1008
|
+
/** Tracking contribution in [0, 1]; older values above 1 normalize to 1. Live changes use scheduled motion. */
|
|
1009
|
+
eyeIntensity?: number;
|
|
1010
|
+
/** Tracking contribution in [0, 1], composed over authored head motion. Live changes use scheduled motion. */
|
|
1011
|
+
headIntensity?: number;
|
|
1012
|
+
initialState?: GazeControlState;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
export interface GazeFocusDiagnostics {
|
|
1016
|
+
target: PolymerVector3;
|
|
1017
|
+
eyes: Array<{ name: string; origin: PolymerVector3; direction: PolymerVector3; errorDegrees: number; limited: boolean }>;
|
|
1018
|
+
headLimited: boolean;
|
|
1019
|
+
missingHead: boolean;
|
|
1020
|
+
missingEyes: boolean;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
export interface GazeObservation {
|
|
1024
|
+
sampleSequence: number;
|
|
1025
|
+
observedAt: number;
|
|
1026
|
+
bindingGeneration: number;
|
|
1027
|
+
requestId: string | null;
|
|
1028
|
+
diagnostics: GazeFocusDiagnostics;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
export interface GazeAttentionOutcome {
|
|
1032
|
+
status: 'moving' | 'settled' | 'unavailable' | 'failed';
|
|
1033
|
+
reason: string;
|
|
1034
|
+
angularErrorDeg?: number;
|
|
1035
|
+
sampleSequence?: number;
|
|
1036
|
+
observedAt?: number;
|
|
1037
|
+
bindingGeneration?: number;
|
|
1038
|
+
}
|
|
1039
|
+
export interface GazeRetainedCandidate {
|
|
1040
|
+
id: string;
|
|
1041
|
+
source: string;
|
|
1042
|
+
provenance: 'synthetic' | 'peer';
|
|
1043
|
+
target: GazeTarget;
|
|
1044
|
+
targetSpace: string;
|
|
1045
|
+
confidence: number;
|
|
1046
|
+
salience: number;
|
|
1047
|
+
influence: number;
|
|
1048
|
+
/** Actual accepted Society credit for peers, null for synthetic fixtures. */
|
|
1049
|
+
routeCredit: number | null;
|
|
1050
|
+
edgeId: string | null;
|
|
1051
|
+
score: number;
|
|
1052
|
+
observedAt: number;
|
|
1053
|
+
expiresAt: number;
|
|
1054
|
+
eligible: boolean;
|
|
1055
|
+
reason: string;
|
|
1056
|
+
lastOutcome?: GazeAttentionOutcome;
|
|
1057
|
+
}
|
|
1058
|
+
export interface GazeAttentionState {
|
|
1059
|
+
/** The POC accepts static Conversation facts; live perception arbitration is deferred. */
|
|
1060
|
+
lastRejectedInput?: { source: string; reason: 'moving-peer-arbitration-deferred' };
|
|
1061
|
+
active: boolean;
|
|
1062
|
+
sessionId: string | null;
|
|
1063
|
+
scenario: GazeAttentionScenario | null;
|
|
1064
|
+
phase: 'inactive' | 'waiting' | 'moving' | 'settled' | 'unavailable' | 'failed';
|
|
1065
|
+
reason: string;
|
|
1066
|
+
selectedId: string | null;
|
|
1067
|
+
requestId: string | null;
|
|
1068
|
+
configurationRevision: number;
|
|
1069
|
+
candidates: GazeRetainedCandidate[];
|
|
1070
|
+
feedback: GazeAttentionOutcome | null;
|
|
1071
|
+
decisionCount: number;
|
|
1072
|
+
updatedAt?: number;
|
|
1073
|
+
}
|
|
1074
|
+
export type GazeAttentionScenario = 'competition' | 'equal-score' | 'expiry' | 'unreachable';
|
|
1075
|
+
|
|
1076
|
+
export interface ScreenSpaceGazeSolution {
|
|
1077
|
+
kind: 'gaze.screen-space' | 'gaze.viewer-space';
|
|
1078
|
+
focus?: GazeFocusRequest;
|
|
1079
|
+
target: Required<GazeTarget>;
|
|
1080
|
+
eyeTarget: Required<GazeTarget>;
|
|
1081
|
+
headTarget: Required<GazeTarget>;
|
|
1082
|
+
angles: {
|
|
1083
|
+
yawDegrees: number;
|
|
1084
|
+
pitchDegrees: number;
|
|
1085
|
+
cameraYawDegrees: number;
|
|
1086
|
+
cameraPitchDegrees: number;
|
|
1087
|
+
};
|
|
1088
|
+
/** World-space distance from the character's binocular eye origin to the render camera. */
|
|
1089
|
+
distance: number;
|
|
1090
|
+
viewerTarget: PolymerVector3;
|
|
1091
|
+
screenTarget: Required<GazeTarget>;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
export interface ScreenSpaceGazeOptions {
|
|
1095
|
+
profile?: Profile;
|
|
1096
|
+
screenTarget: GazeTarget;
|
|
1097
|
+
cameraPosition: PolymerVector3;
|
|
1098
|
+
cameraQuaternion: PolymerQuaternion;
|
|
1099
|
+
gazeOrigin: PolymerVector3;
|
|
1100
|
+
modelQuaternion: PolymerQuaternion;
|
|
1101
|
+
verticalFovDegrees: number;
|
|
1102
|
+
aspect: number;
|
|
1103
|
+
eyesEnabled?: boolean;
|
|
1104
|
+
headEnabled?: boolean;
|
|
1105
|
+
/** Defaults to 1: full target bearing, bounded by the profile's head AU limits. */
|
|
1106
|
+
headFollowFraction?: number;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
export interface CameraGazeGeometry {
|
|
1110
|
+
cameraPosition: PolymerVector3;
|
|
1111
|
+
cameraQuaternion: PolymerQuaternion;
|
|
1112
|
+
gazeOrigin: PolymerVector3;
|
|
1113
|
+
modelQuaternion: PolymerQuaternion;
|
|
1114
|
+
verticalFovDegrees: number;
|
|
1115
|
+
aspect: number;
|
|
1116
|
+
gazeGeometryComplete: boolean;
|
|
1117
|
+
worldUnitsPerMeter?: number;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
export interface EmbodyGazeRuntime {
|
|
1121
|
+
solveTarget(
|
|
1122
|
+
screenTarget: GazeTarget,
|
|
1123
|
+
cameraFact: CameraGazeGeometry & Record<string, unknown>,
|
|
1124
|
+
options: GazeApplyOptions & { eyesEnabled: boolean; headEnabled: boolean; headFollowEyes: boolean; headIntensity?: number }
|
|
1125
|
+
): ScreenSpaceGazeSolution;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
477
1128
|
export interface GazeConfig {
|
|
1129
|
+
/** Explicitly synthetic lab:A and lab:B receiver influences, not graph-edge weights. */
|
|
1130
|
+
attentionInfluenceA?: number;
|
|
1131
|
+
attentionInfluenceB?: number;
|
|
1132
|
+
attentionDwellMs?: number;
|
|
1133
|
+
attentionSwitchMargin?: number;
|
|
1134
|
+
attentionToleranceDeg?: number;
|
|
1135
|
+
attentionTimeoutMs?: number;
|
|
478
1136
|
enabled?: boolean;
|
|
479
1137
|
eyesEnabled?: boolean;
|
|
480
1138
|
headEnabled?: boolean;
|
|
1139
|
+
/** Default true: follow the full target turn from reference neutral within head AU limits. False prefers neutral, with eye-limit overflow assistance. */
|
|
481
1140
|
headFollowEyes?: boolean;
|
|
1141
|
+
headFollowDelay?: number;
|
|
482
1142
|
mirrored?: boolean;
|
|
483
1143
|
smoothFactor?: number;
|
|
1144
|
+
predictionEnabled?: boolean;
|
|
1145
|
+
predictionFactor?: number;
|
|
1146
|
+
maxPredictionDelta?: number;
|
|
484
1147
|
minDelta?: number;
|
|
485
1148
|
transitionDurationMs?: number;
|
|
1149
|
+
/** Tracking contribution in [0, 1]; older values above 1 normalize to 1. With geometry-backed focus, live changes move directly toward the latest value without angular reversal braking. */
|
|
486
1150
|
eyeIntensity?: number;
|
|
1151
|
+
/** Tracking contribution in [0, 1], composed over authored head motion. With geometry-backed focus, live changes move directly toward the latest value without angular reversal braking. */
|
|
487
1152
|
headIntensity?: number;
|
|
1153
|
+
trackingSpeed?: number;
|
|
1154
|
+
/** Braking interval for angular direction changes; geometry-backed strength changes bypass it. */
|
|
1155
|
+
courseChangeDurationMs?: number;
|
|
488
1156
|
coalesceMs?: number;
|
|
489
1157
|
}
|
|
490
1158
|
|
|
491
1159
|
export interface GazeState {
|
|
1160
|
+
attention: GazeAttentionState;
|
|
1161
|
+
configuration: AgencyConfigurationState;
|
|
1162
|
+
lastDecision: GazeDecision | null;
|
|
492
1163
|
agency: 'gaze';
|
|
493
1164
|
status: string;
|
|
494
1165
|
mode: string;
|
|
@@ -496,8 +1167,12 @@ export interface GazeState {
|
|
|
496
1167
|
rawTarget: Required<GazeTarget>;
|
|
497
1168
|
target: Required<GazeTarget>;
|
|
498
1169
|
baseTarget: Required<GazeTarget>;
|
|
1170
|
+
baseOptions: GazeApplyOptions;
|
|
1171
|
+
cameraInvalidated: boolean;
|
|
1172
|
+
sourceAvailable: boolean;
|
|
499
1173
|
cameraRelativeOffset: Required<GazeTarget>;
|
|
500
1174
|
lastCameraFact: null | Record<string, unknown>;
|
|
1175
|
+
lastGazeSolution: ScreenSpaceGazeSolution | null;
|
|
501
1176
|
lastRequestedTarget: Required<GazeTarget>;
|
|
502
1177
|
pendingRequest: GazeLookRequest | null;
|
|
503
1178
|
lastRequest: GazeLookRequest | GazeResetRequest | null;
|
|
@@ -517,11 +1192,22 @@ export interface GazeApplyOptions {
|
|
|
517
1192
|
eyeEnabled?: boolean;
|
|
518
1193
|
headEnabled?: boolean;
|
|
519
1194
|
headFollowEyes?: boolean;
|
|
1195
|
+
headFollowDelay?: number;
|
|
1196
|
+
/** Fraction of total target bearing assigned to the head from reference neutral. Defaults to 1; head AU limits still apply. */
|
|
1197
|
+
headFollowFraction?: number;
|
|
1198
|
+
viewerTarget?: PolymerVector3;
|
|
1199
|
+
viewerTargetSpace?: 'webcam.viewer';
|
|
1200
|
+
viewerVerticalFovDegrees?: number;
|
|
1201
|
+
viewerAspect?: number;
|
|
1202
|
+
rawViewerTarget?: PolymerVector3;
|
|
1203
|
+
/** Default false. True explicitly prefers the camera bearing instead of reference-neutral target following. */
|
|
1204
|
+
lockHeadToCamera?: boolean;
|
|
520
1205
|
force?: boolean;
|
|
521
1206
|
}
|
|
522
1207
|
|
|
523
1208
|
export interface GazeAttentionCandidate {
|
|
524
1209
|
target?: GazeTarget;
|
|
1210
|
+
screenTarget?: GazeTarget;
|
|
525
1211
|
gazeTarget?: GazeTarget;
|
|
526
1212
|
lookTarget?: GazeTarget;
|
|
527
1213
|
x?: number;
|
|
@@ -536,19 +1222,25 @@ export interface GazeAttentionCandidate {
|
|
|
536
1222
|
}
|
|
537
1223
|
|
|
538
1224
|
export type GazeDispatch =
|
|
1225
|
+
| { type: 'attention.start' | 'attention.stop'; sessionId: string }
|
|
1226
|
+
| { type: 'attention.scenario'; sessionId: string; scenario: GazeAttentionScenario }
|
|
539
1227
|
| { type: 'configure'; config: GazeConfig }
|
|
540
1228
|
| { type: 'setMode' | 'set-mode'; mode: string }
|
|
541
1229
|
| { type: 'setActive' | 'set-active'; active: boolean }
|
|
542
1230
|
| { type: 'enable' }
|
|
543
1231
|
| { type: 'disable' }
|
|
544
1232
|
| { type: 'setTarget' | 'set-target' | 'focusTarget'; target: GazeTarget; options?: GazeApplyOptions }
|
|
545
|
-
| { type: 'attention.fact'; targets?: GazeAttentionCandidate[]; target?: GazeTarget; source?: string }
|
|
546
|
-
| { type: 'camera.fact'; relativeOffset: GazeTarget; source?: string }
|
|
1233
|
+
| { type: 'attention.fact'; targets?: GazeAttentionCandidate[]; target?: GazeTarget; screenTarget?: GazeTarget; targetSpace?: string; source?: string }
|
|
1234
|
+
| ({ type: 'camera.fact'; relativeOffset: GazeTarget; source?: string } & Partial<CameraGazeGeometry>)
|
|
547
1235
|
| { type: 'camera.stale' | 'clearCameraOffset'; reason?: string; source?: string }
|
|
1236
|
+
| Extract<PolymerDomainEvent, { type: 'userPerception.faceLost' | 'userPerception.status' }>
|
|
548
1237
|
| { type: 'reset'; durationMs?: number; eyes?: boolean; head?: boolean }
|
|
549
1238
|
| { type: 'cancel'; reason?: string };
|
|
550
1239
|
|
|
551
1240
|
export interface GazeLookRequest {
|
|
1241
|
+
attentionFeedback?: { sessionId: string; requestId: string; worldTarget: PolymerVector3 | null; timeoutMs: number; toleranceDeg: number } | null;
|
|
1242
|
+
configurationRevision?: number;
|
|
1243
|
+
coalesceMs?: number;
|
|
552
1244
|
type: 'eyeHeadTracking.requestGaze';
|
|
553
1245
|
agency: 'gaze';
|
|
554
1246
|
targetAgency: 'eyeHeadTracking';
|
|
@@ -557,7 +1249,12 @@ export interface GazeLookRequest {
|
|
|
557
1249
|
label?: string;
|
|
558
1250
|
mode: string;
|
|
559
1251
|
target: Required<GazeTarget>;
|
|
1252
|
+
eyeTarget: Required<GazeTarget>;
|
|
1253
|
+
headTarget: Required<GazeTarget>;
|
|
1254
|
+
gazeSolution?: ScreenSpaceGazeSolution;
|
|
560
1255
|
rawTarget: Required<GazeTarget>;
|
|
1256
|
+
predictedTarget: Required<GazeTarget>;
|
|
1257
|
+
predictive: boolean;
|
|
561
1258
|
previousTarget: Required<GazeTarget>;
|
|
562
1259
|
eyeEnabled: boolean;
|
|
563
1260
|
headEnabled: boolean;
|
|
@@ -605,9 +1302,14 @@ export interface EyeHeadTrackingConfig {
|
|
|
605
1302
|
lookAtSpeaker?: boolean;
|
|
606
1303
|
idleVariation?: boolean;
|
|
607
1304
|
idleVariationInterval?: number;
|
|
1305
|
+
/** Tracking contribution in [0, 1]; older values above 1 normalize to 1. With geometry-backed focus, live changes move toward the latest value without angular reversal braking. */
|
|
608
1306
|
eyeIntensity?: number;
|
|
609
1307
|
eyeBlendWeight?: number;
|
|
1308
|
+
/** Tracking contribution in [0, 1], composed over authored head motion. With geometry-backed focus, live changes move toward the latest value without angular reversal braking. */
|
|
610
1309
|
headIntensity?: number;
|
|
1310
|
+
trackingSpeed?: number;
|
|
1311
|
+
/** Angular braking interval; geometry-backed strength changes bypass it. */
|
|
1312
|
+
courseChangeDurationMs?: number;
|
|
611
1313
|
headBlendWeight?: number;
|
|
612
1314
|
headRoll?: number;
|
|
613
1315
|
eyePriority?: number;
|
|
@@ -656,12 +1358,19 @@ export interface EyeHeadGazeRequest {
|
|
|
656
1358
|
sourceAgency?: string;
|
|
657
1359
|
requestId: string;
|
|
658
1360
|
target: Required<GazeTarget>;
|
|
1361
|
+
eyeTarget?: Required<GazeTarget>;
|
|
1362
|
+
headTarget?: Required<GazeTarget>;
|
|
1363
|
+
gazeSolution?: ScreenSpaceGazeSolution;
|
|
1364
|
+
gazeFocus?: GazeFocusRequest;
|
|
659
1365
|
rawTarget?: Required<GazeTarget>;
|
|
660
1366
|
mode?: string;
|
|
661
1367
|
eyeEnabled?: boolean;
|
|
662
1368
|
headEnabled?: boolean;
|
|
663
1369
|
headFollowEyes?: boolean;
|
|
1370
|
+
headFollowDelay?: number;
|
|
1371
|
+
/** Tracking contribution in [0, 1]; older values above 1 normalize to 1. Live changes use scheduled motion. */
|
|
664
1372
|
eyeIntensity?: number;
|
|
1373
|
+
/** Tracking contribution in [0, 1], composed over authored head motion. Live changes use scheduled motion. */
|
|
665
1374
|
headIntensity?: number;
|
|
666
1375
|
headRoll?: number;
|
|
667
1376
|
eyeDurationMs?: number;
|
|
@@ -709,11 +1418,37 @@ export interface AnimationScheduledSnippet {
|
|
|
709
1418
|
snippetCategory?: string;
|
|
710
1419
|
snippetPriority?: number;
|
|
711
1420
|
maxTime?: number;
|
|
1421
|
+
cleanupMaxTime?: number;
|
|
712
1422
|
loop: boolean;
|
|
713
1423
|
autoPlay: boolean;
|
|
714
1424
|
requestedAt: number;
|
|
715
1425
|
}
|
|
716
1426
|
|
|
1427
|
+
export interface AnimationBakedClipInfo {
|
|
1428
|
+
name: string;
|
|
1429
|
+
duration: number;
|
|
1430
|
+
channels: unknown[];
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
export interface AnimationBakedUIState {
|
|
1434
|
+
name: string;
|
|
1435
|
+
source: 'baked';
|
|
1436
|
+
time: number;
|
|
1437
|
+
currentTime: number;
|
|
1438
|
+
duration: number;
|
|
1439
|
+
speed: number;
|
|
1440
|
+
playbackRate: number;
|
|
1441
|
+
intensityScale: number;
|
|
1442
|
+
isPlaying: boolean;
|
|
1443
|
+
isPaused: boolean;
|
|
1444
|
+
loop: boolean;
|
|
1445
|
+
loopMode: string;
|
|
1446
|
+
reverse: boolean;
|
|
1447
|
+
category: 'baked';
|
|
1448
|
+
channels: unknown[];
|
|
1449
|
+
[key: string]: unknown;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
717
1452
|
export interface AnimationState {
|
|
718
1453
|
agency: 'animation';
|
|
719
1454
|
scheduled: Record<string, AnimationScheduledSnippet>;
|
|
@@ -722,18 +1457,30 @@ export interface AnimationState {
|
|
|
722
1457
|
seekCount: number;
|
|
723
1458
|
updatedCount: number;
|
|
724
1459
|
removedCount: number;
|
|
1460
|
+
bakedClips: AnimationBakedClipInfo[];
|
|
1461
|
+
bakedByName: Record<string, AnimationBakedUIState>;
|
|
1462
|
+
bakedPlaying: AnimationBakedUIState[];
|
|
725
1463
|
lastEvent: null | {
|
|
726
1464
|
type:
|
|
727
1465
|
| 'animationSnippetScheduled'
|
|
728
1466
|
| 'animationSnippetStarted'
|
|
729
1467
|
| 'animationSnippetSeeked'
|
|
730
1468
|
| 'animationSnippetUpdated'
|
|
731
|
-
| 'animationSnippetRemoved'
|
|
732
|
-
|
|
733
|
-
|
|
1469
|
+
| 'animationSnippetRemoved'
|
|
1470
|
+
| 'animationBakedClipsLoaded'
|
|
1471
|
+
| 'animationBakedStarted'
|
|
1472
|
+
| 'animationBakedStopped'
|
|
1473
|
+
| 'animationBakedPaused'
|
|
1474
|
+
| 'animationBakedResumed'
|
|
1475
|
+
| 'animationBakedSeeked'
|
|
1476
|
+
| 'animationBakedUpdated';
|
|
1477
|
+
name?: string;
|
|
1478
|
+
clipName?: string;
|
|
1479
|
+
sourceAgency?: string;
|
|
734
1480
|
reason?: string;
|
|
735
1481
|
offsetSec?: number;
|
|
736
1482
|
params?: Record<string, unknown>;
|
|
1483
|
+
count?: number;
|
|
737
1484
|
at: number;
|
|
738
1485
|
};
|
|
739
1486
|
}
|
|
@@ -754,7 +1501,15 @@ export type AnimationDispatch =
|
|
|
754
1501
|
| { type: 'seekSnippet'; sourceAgency?: string; name: string; offsetSec: number }
|
|
755
1502
|
| { type: 'updateSnippet'; sourceAgency?: string; name: string; params: Record<string, unknown> }
|
|
756
1503
|
| { type: 'removeSnippet'; sourceAgency?: string; name: string }
|
|
757
|
-
| { type: 'clear'; sourceAgency?: string }
|
|
1504
|
+
| { type: 'clear'; sourceAgency?: string }
|
|
1505
|
+
| { type: 'loadBakedClips'; sourceAgency?: string; clips?: AnimationBakedClipInfo[] }
|
|
1506
|
+
| { type: 'playBaked'; sourceAgency?: string; name: string; options?: Record<string, unknown> }
|
|
1507
|
+
| { type: 'stopBaked'; sourceAgency?: string; name: string }
|
|
1508
|
+
| { type: 'pauseBaked'; sourceAgency?: string; name: string }
|
|
1509
|
+
| { type: 'resumeBaked'; sourceAgency?: string; name: string }
|
|
1510
|
+
| { type: 'seekBaked'; sourceAgency?: string; name: string; offsetSec: number }
|
|
1511
|
+
| { type: 'updateBakedParams'; sourceAgency?: string; name: string; params: Record<string, unknown> }
|
|
1512
|
+
| { type: 'stopAllBaked'; sourceAgency?: string };
|
|
758
1513
|
|
|
759
1514
|
export interface PolymerSnippetKeyframe {
|
|
760
1515
|
time: number;
|
|
@@ -792,6 +1547,8 @@ export interface PolymerAnimationHandle {
|
|
|
792
1547
|
}
|
|
793
1548
|
|
|
794
1549
|
export interface PolymerAnimationRuntime {
|
|
1550
|
+
/** Optional capability. Unsupported engines never produce confirmed Gaze alignment. */
|
|
1551
|
+
getGazeObservation?: () => GazeObservation | null;
|
|
795
1552
|
buildClip?: (
|
|
796
1553
|
name: string,
|
|
797
1554
|
curves: Record<string, PolymerSnippetKeyframe[]>,
|
|
@@ -825,27 +1582,60 @@ export interface PolymerAnimationSnippet {
|
|
|
825
1582
|
curves?: Record<string, PolymerSnippetKeyframe[]>;
|
|
826
1583
|
channels?: PolymerSnippetChannel[];
|
|
827
1584
|
maxTime: number;
|
|
1585
|
+
/** Optional visual curve end used for cleanup when it outlives the sync clock. */
|
|
1586
|
+
cleanupMaxTime?: number;
|
|
828
1587
|
loop: boolean;
|
|
829
1588
|
snippetCategory?: string;
|
|
830
1589
|
snippetPriority: number;
|
|
831
1590
|
snippetPlaybackRate: number;
|
|
832
1591
|
snippetIntensityScale: number;
|
|
1592
|
+
snippetBlendMode?: 'replace' | 'additive';
|
|
1593
|
+
/** Neutral reference sample for converting a clip to additive rotation. */
|
|
1594
|
+
additiveReferenceTimeSec?: number;
|
|
1595
|
+
/** Stable order for zero-fade, once-only additive controls, even after other clips are removed. */
|
|
1596
|
+
additiveCompositionOrder?: number;
|
|
833
1597
|
snippetJawScale?: number;
|
|
834
1598
|
autoVisemeJaw?: boolean;
|
|
835
1599
|
metadata?: Record<string, unknown>;
|
|
836
1600
|
}
|
|
837
1601
|
|
|
838
1602
|
export interface LipSyncConfig {
|
|
1603
|
+
/**
|
|
1604
|
+
* Resolve from the active runtime profile once per profile change. Explicitly configuring
|
|
1605
|
+
* this field rebuilds an active clip even when equal (setProfile may clear runtime actions).
|
|
1606
|
+
* Null retains legacy canonical routing. Never configure it every frame.
|
|
1607
|
+
*/
|
|
1608
|
+
visemeProfile?: ResolvedVisemeProfile | null;
|
|
839
1609
|
intensity?: number;
|
|
840
1610
|
speechRate?: number;
|
|
841
1611
|
jawScale?: number;
|
|
842
1612
|
/** Scale for independently planned tongue AU curves. Set 0 to disable tongue motion. */
|
|
843
1613
|
tongueScale?: number;
|
|
844
|
-
rampMs?: number;
|
|
845
|
-
holdMs?: number;
|
|
846
1614
|
priority?: number;
|
|
1615
|
+
/**
|
|
1616
|
+
* Scales the shared viseme-to-viseme handoff window. Higher values produce a
|
|
1617
|
+
* longer pose blend without returning the mouth to neutral. Default 1.75.
|
|
1618
|
+
*/
|
|
1619
|
+
envelopeTimeScale?: number;
|
|
847
1620
|
visualLeadMs?: number;
|
|
1621
|
+
/** Mixer fade-in for the scheduled utterance clip (seconds). Default 0.15. */
|
|
1622
|
+
fadeInSec?: number;
|
|
1623
|
+
/** Mixer fade-out when the utterance is stopped or replaced (seconds). Default 0.12. */
|
|
1624
|
+
fadeOutSec?: number;
|
|
1625
|
+
/** Mixer blend mode: "replace" (default) or "additive". */
|
|
1626
|
+
blendMode?: 'replace' | 'additive' | string;
|
|
1627
|
+
/**
|
|
1628
|
+
* Keyframe easing applied by the Embody host when densifying scalar tracks.
|
|
1629
|
+
* Default "easeInOutCubic".
|
|
1630
|
+
*/
|
|
1631
|
+
easing?: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'easeInOutCubic' | string;
|
|
1632
|
+
webSpeechDriftThresholdSec?: number;
|
|
1633
|
+
azureDriftThresholdSec?: number;
|
|
848
1634
|
wordDriftThresholdSec?: number;
|
|
1635
|
+
/** Per-viseme jaw opening amounts, usually from the character profile. */
|
|
1636
|
+
visemeJawAmounts?: number[];
|
|
1637
|
+
/** Per-viseme tongue AU targets, supplied by the resolved character preset/profile. */
|
|
1638
|
+
visemeTongueTargets?: VisemeTongueTarget[];
|
|
849
1639
|
}
|
|
850
1640
|
|
|
851
1641
|
export interface LipSyncRuntime {
|
|
@@ -858,13 +1648,11 @@ export interface LipSyncRuntime {
|
|
|
858
1648
|
}
|
|
859
1649
|
|
|
860
1650
|
export interface LipSyncVisemeEvent {
|
|
1651
|
+
/** Canonical articulation ID, independent of the destination model slot. */
|
|
861
1652
|
visemeId: number;
|
|
862
|
-
/**
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
* lip-only viseme, or scale with LipSyncConfig.jawScale for JALI-style control.
|
|
866
|
-
*/
|
|
867
|
-
jawActivation?: number;
|
|
1653
|
+
/** Optional explicit provider identity; unknown/ambiguous routes remain neutral. */
|
|
1654
|
+
provider?: string;
|
|
1655
|
+
providerId?: string | number;
|
|
868
1656
|
phoneme?: string;
|
|
869
1657
|
/**
|
|
870
1658
|
* Primary visual-speech class for planner rules, e.g. vowel, bilabial,
|
|
@@ -908,6 +1696,14 @@ export interface LipSyncTimeline {
|
|
|
908
1696
|
durationSec?: number;
|
|
909
1697
|
}
|
|
910
1698
|
|
|
1699
|
+
/** Voice facts TTS relays with an utterance. Only speechRate is acted on today. */
|
|
1700
|
+
export interface LipSyncVoiceFacts {
|
|
1701
|
+
speechRate?: number;
|
|
1702
|
+
volume?: number;
|
|
1703
|
+
pitch?: number;
|
|
1704
|
+
style?: string;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
911
1707
|
export interface LipSyncState {
|
|
912
1708
|
agency: 'lipSync';
|
|
913
1709
|
speaking: boolean;
|
|
@@ -916,6 +1712,7 @@ export interface LipSyncState {
|
|
|
916
1712
|
snippetName: string | null;
|
|
917
1713
|
source: string | null;
|
|
918
1714
|
text: string | null;
|
|
1715
|
+
voice: LipSyncVoiceFacts | null;
|
|
919
1716
|
startTime: number | null;
|
|
920
1717
|
audioStartedAt: number | null;
|
|
921
1718
|
audioTimeSec: number | null;
|
|
@@ -925,7 +1722,12 @@ export interface LipSyncState {
|
|
|
925
1722
|
scheduledCount: number;
|
|
926
1723
|
stoppedCount: number;
|
|
927
1724
|
syncCorrectionCount: number;
|
|
928
|
-
|
|
1725
|
+
rebuildCount: number;
|
|
1726
|
+
config: Required<Omit<LipSyncConfig, 'visemeJawAmounts' | 'visemeTongueTargets' | 'visemeProfile'>> & {
|
|
1727
|
+
visemeProfile: ResolvedVisemeProfile | null;
|
|
1728
|
+
visemeJawAmounts: number[] | null;
|
|
1729
|
+
visemeTongueTargets: VisemeTongueTarget[] | null;
|
|
1730
|
+
};
|
|
929
1731
|
lastEvent: null | Record<string, unknown>;
|
|
930
1732
|
}
|
|
931
1733
|
|
|
@@ -939,6 +1741,10 @@ export type LipSyncDispatch =
|
|
|
939
1741
|
wordTimings?: LipSyncWordTiming[];
|
|
940
1742
|
durationSec?: number;
|
|
941
1743
|
totalDurationMs?: number;
|
|
1744
|
+
speechRate?: number;
|
|
1745
|
+
volume?: number;
|
|
1746
|
+
pitch?: number;
|
|
1747
|
+
style?: string;
|
|
942
1748
|
}
|
|
943
1749
|
| { type: 'startTimeline'; timeline: LipSyncTimeline }
|
|
944
1750
|
| {
|
|
@@ -949,6 +1755,10 @@ export type LipSyncDispatch =
|
|
|
949
1755
|
text?: string;
|
|
950
1756
|
source?: string;
|
|
951
1757
|
wordTimings?: LipSyncWordTiming[];
|
|
1758
|
+
speechRate?: number;
|
|
1759
|
+
volume?: number;
|
|
1760
|
+
pitch?: number;
|
|
1761
|
+
style?: string;
|
|
952
1762
|
options?: { wordTimings?: LipSyncWordTiming[]; visualLeadMs?: number; [key: string]: unknown };
|
|
953
1763
|
}
|
|
954
1764
|
| { type: 'wordBoundary'; word: string; wordIndex?: number; observedElapsedSec?: number; hostElapsedSec?: number }
|
|
@@ -965,6 +1775,8 @@ export interface TTSVoice {
|
|
|
965
1775
|
lang?: string;
|
|
966
1776
|
gender?: string;
|
|
967
1777
|
styles?: string[];
|
|
1778
|
+
/** False for Google/network Web Speech voices that omit onboundary events. */
|
|
1779
|
+
localService?: boolean;
|
|
968
1780
|
provider?: 'webSpeech' | 'azure' | string;
|
|
969
1781
|
}
|
|
970
1782
|
|
|
@@ -975,16 +1787,10 @@ export interface TTSConfig {
|
|
|
975
1787
|
azureVoiceName?: string;
|
|
976
1788
|
azureStyle?: string;
|
|
977
1789
|
azureStyleDegree?: string | number | null;
|
|
1790
|
+
/** Voice facts. Relayed to LipSync on each utterance; rate is live today. */
|
|
978
1791
|
rate?: number;
|
|
979
1792
|
pitch?: number;
|
|
980
1793
|
volume?: number;
|
|
981
|
-
visualLeadMs?: number;
|
|
982
|
-
lipsyncIntensity?: number;
|
|
983
|
-
jawScale?: number;
|
|
984
|
-
/** Scale for LipSync tongue AU planning forwarded by TTS before each speech session. */
|
|
985
|
-
tongueScale?: number;
|
|
986
|
-
webSpeechDriftThresholdSec?: number;
|
|
987
|
-
azureDriftThresholdSec?: number;
|
|
988
1794
|
azureCacheLimit?: number;
|
|
989
1795
|
debug?: boolean;
|
|
990
1796
|
/** Experimental Web Speech barge-in reference: none | displayMedia */
|
|
@@ -1018,6 +1824,9 @@ export type TTSDispatch =
|
|
|
1018
1824
|
| {
|
|
1019
1825
|
type: 'speak';
|
|
1020
1826
|
text: string;
|
|
1827
|
+
turnId?: string;
|
|
1828
|
+
requestId?: string;
|
|
1829
|
+
speechId?: string;
|
|
1021
1830
|
engine?: 'webSpeech' | 'azure' | 'livekit' | string;
|
|
1022
1831
|
name?: string;
|
|
1023
1832
|
backendUrl?: string;
|
|
@@ -1026,17 +1835,161 @@ export type TTSDispatch =
|
|
|
1026
1835
|
rate?: number;
|
|
1027
1836
|
pitch?: number;
|
|
1028
1837
|
volume?: number;
|
|
1029
|
-
visualLeadMs?: number;
|
|
1030
1838
|
}
|
|
1031
|
-
| { type: '
|
|
1839
|
+
| { type: 'releasePlaybackReference' }
|
|
1840
|
+
| { type: 'stop'; reason?: string; turnId?: string; requestId?: string; speechId?: string }
|
|
1032
1841
|
| { type: 'reset' };
|
|
1033
1842
|
|
|
1843
|
+
export type ProsodicProfileSnippet = Record<string, unknown> & {
|
|
1844
|
+
name: string;
|
|
1845
|
+
};
|
|
1846
|
+
|
|
1847
|
+
export type ProsodicProfileSnippetInput =
|
|
1848
|
+
| ProsodicProfileSnippet
|
|
1849
|
+
| ({ snippet: ProsodicProfileSnippet } & Record<string, unknown>);
|
|
1850
|
+
|
|
1034
1851
|
export interface ProsodicConfig {
|
|
1035
1852
|
enabled?: boolean;
|
|
1036
1853
|
intensity?: number;
|
|
1037
1854
|
priority?: number;
|
|
1038
1855
|
speechGestureEvery?: number;
|
|
1856
|
+
browPulseEvery?: number;
|
|
1857
|
+
headPulseEvery?: number;
|
|
1858
|
+
browIntensity?: number;
|
|
1859
|
+
headIntensity?: number;
|
|
1860
|
+
openingMovement?: boolean;
|
|
1039
1861
|
blinkFastCooldownMs?: number;
|
|
1862
|
+
/** Saved speaking brow snippet selected by the active character profile. */
|
|
1863
|
+
browSnippet?: ProsodicProfileSnippetInput;
|
|
1864
|
+
/** Saved speaking head snippet selected by the active character profile. */
|
|
1865
|
+
headSnippet?: ProsodicProfileSnippetInput;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
/** Supported portable live settings; asset bodies and private clocks are not authored here. */
|
|
1869
|
+
export type ProsodicEditableConfiguration = Pick<ProsodicConfig,
|
|
1870
|
+
'headIntensity' | 'browIntensity' | 'headPulseEvery' | 'browPulseEvery' | 'openingMovement'>;
|
|
1871
|
+
|
|
1872
|
+
/** Scalar policy fields supported by an agency's revisioned apply API. */
|
|
1873
|
+
export interface AgencyParameter<Key extends string = string> {
|
|
1874
|
+
key: Key;
|
|
1875
|
+
label: string;
|
|
1876
|
+
type: 'number' | 'boolean';
|
|
1877
|
+
default: number | boolean;
|
|
1878
|
+
minimum?: number;
|
|
1879
|
+
maximum?: number;
|
|
1880
|
+
step?: number;
|
|
1881
|
+
unit?: string;
|
|
1882
|
+
description: string;
|
|
1883
|
+
applyBoundary: 'next-decision';
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
export interface AgencyConfigurationReceipt {
|
|
1887
|
+
status: 'applied' | 'rejected';
|
|
1888
|
+
requestedRevision: number;
|
|
1889
|
+
appliedRevision: number;
|
|
1890
|
+
reason?: string;
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
export interface AgencyConfigurationState {
|
|
1894
|
+
appliedRevision: number;
|
|
1895
|
+
applyBoundary: 'next-decision';
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
export interface ProsodicParameter extends AgencyParameter<keyof ProsodicEditableConfiguration> {}
|
|
1899
|
+
|
|
1900
|
+
export type GestureEditableConfiguration = Pick<GestureConfig,
|
|
1901
|
+
'intensity' | 'priority' | 'defaultDurationMs' | 'cooldownMs' | 'rampRatio'
|
|
1902
|
+
| 'holdRatio' | 'returnToBase' | 'replaceActive' | 'maxActive'>;
|
|
1903
|
+
export type GazeEditableConfiguration = Pick<GazeConfig,
|
|
1904
|
+
'headFollowDelay' | 'predictionEnabled' | 'trackingSpeed' | 'coalesceMs'
|
|
1905
|
+
| 'attentionInfluenceA' | 'attentionInfluenceB' | 'attentionDwellMs'
|
|
1906
|
+
| 'attentionSwitchMargin' | 'attentionToleranceDeg' | 'attentionTimeoutMs'>;
|
|
1907
|
+
export type CameraContextEditableConfiguration = Pick<CameraContextConfig,
|
|
1908
|
+
'coalesceMs' | 'staleAfterMs' | 'yawWeight' | 'pitchWeight'>;
|
|
1909
|
+
|
|
1910
|
+
export interface GestureDefinition {
|
|
1911
|
+
id: 'gesture';
|
|
1912
|
+
family: 'action';
|
|
1913
|
+
definitionVersion: 1;
|
|
1914
|
+
parameters: AgencyParameter<keyof GestureEditableConfiguration>[];
|
|
1915
|
+
}
|
|
1916
|
+
export interface GazeDefinition {
|
|
1917
|
+
id: 'gaze';
|
|
1918
|
+
family: 'cognition';
|
|
1919
|
+
definitionVersion: 2;
|
|
1920
|
+
parameters: AgencyParameter<keyof GazeEditableConfiguration>[];
|
|
1921
|
+
}
|
|
1922
|
+
export interface CameraContextDefinition {
|
|
1923
|
+
id: 'cameraContext';
|
|
1924
|
+
family: 'perception';
|
|
1925
|
+
definitionVersion: 1;
|
|
1926
|
+
parameters: AgencyParameter<keyof CameraContextEditableConfiguration>[];
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
/** Safe decision projection, not an execution receipt or replay record. */
|
|
1930
|
+
export interface GazeDecision {
|
|
1931
|
+
trigger: string;
|
|
1932
|
+
configurationRevision: number;
|
|
1933
|
+
source: string;
|
|
1934
|
+
mode: string;
|
|
1935
|
+
predictive: boolean;
|
|
1936
|
+
outcome: 'requested' | 'reset-requested' | 'cancel-requested' | 'ignored' | 'rejected' | 'state-updated';
|
|
1937
|
+
reason: string | null;
|
|
1938
|
+
confirmation: 'unobserved';
|
|
1939
|
+
at: number;
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
export interface GestureDecision {
|
|
1943
|
+
sequence: number;
|
|
1944
|
+
trigger: string;
|
|
1945
|
+
configurationRevision: number;
|
|
1946
|
+
at: number;
|
|
1947
|
+
status: 'requested' | 'not-requested';
|
|
1948
|
+
reason: string | null;
|
|
1949
|
+
activeRequestCount: number;
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
export interface CameraContextDecision {
|
|
1953
|
+
sequence: number;
|
|
1954
|
+
configurationRevision: number;
|
|
1955
|
+
outcome: 'requested' | 'published';
|
|
1956
|
+
observedAt: number;
|
|
1957
|
+
publishedAt?: number;
|
|
1958
|
+
gazeGeometryComplete: boolean;
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
export interface ProsodicDefinition {
|
|
1962
|
+
id: 'prosodic';
|
|
1963
|
+
family: 'action';
|
|
1964
|
+
definitionVersion: 1;
|
|
1965
|
+
parameters: ProsodicParameter[];
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
export interface ProsodicOptions extends ProsodicConfig {
|
|
1969
|
+
/** Private constructor-only millisecond clock for synthetic fixtures. Never serialized. */
|
|
1970
|
+
now?: () => number;
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
export interface ProsodicConfigurationReceipt extends AgencyConfigurationReceipt {}
|
|
1974
|
+
|
|
1975
|
+
/** A compact inspection projection, not a complete captured-session replay record. */
|
|
1976
|
+
export interface ProsodicDecision {
|
|
1977
|
+
sequence: number;
|
|
1978
|
+
trigger: string;
|
|
1979
|
+
configurationRevision: number;
|
|
1980
|
+
at: number;
|
|
1981
|
+
outcomes: Array<
|
|
1982
|
+
| {
|
|
1983
|
+
status: 'selected';
|
|
1984
|
+
gesture: string;
|
|
1985
|
+
name: string;
|
|
1986
|
+
effectivePeak: number;
|
|
1987
|
+
/** Request emitted, not a rendered-frame acknowledgment. */
|
|
1988
|
+
outcome: 'requested';
|
|
1989
|
+
}
|
|
1990
|
+
| { status: 'missing-asset'; gesture: string; reason: string }
|
|
1991
|
+
| { status: 'suppressed'; reason: string }
|
|
1992
|
+
>;
|
|
1040
1993
|
}
|
|
1041
1994
|
|
|
1042
1995
|
export interface ProsodicState {
|
|
@@ -1049,7 +2002,23 @@ export interface ProsodicState {
|
|
|
1049
2002
|
removedCount: number;
|
|
1050
2003
|
lastGesture: string | null;
|
|
1051
2004
|
lastBlinkFastCueAt: number;
|
|
1052
|
-
|
|
2005
|
+
loadedSnippetNames: string[];
|
|
2006
|
+
config: Required<Omit<ProsodicConfig, 'browSnippet' | 'headSnippet'>>;
|
|
2007
|
+
configuration: { appliedRevision: number; applyBoundary: 'next-decision' };
|
|
2008
|
+
lifecycle: 'active' | 'quiescing' | 'disabled' | 'disposed';
|
|
2009
|
+
routingEnabled: boolean;
|
|
2010
|
+
cleanup: {
|
|
2011
|
+
status: 'not-requested' | 'requested';
|
|
2012
|
+
requestedNames: string[];
|
|
2013
|
+
requestedAt?: number;
|
|
2014
|
+
reason?: string;
|
|
2015
|
+
/** Prosodic does not receive runtime cleanup acknowledgments in this pilot. */
|
|
2016
|
+
confirmation: 'unobserved';
|
|
2017
|
+
};
|
|
2018
|
+
scheduler: { retained: number; limit: number; nextSequence: number; dropped: number };
|
|
2019
|
+
lastDecision: ProsodicDecision | null;
|
|
2020
|
+
rejectedCommandCount: number;
|
|
2021
|
+
lastCommandRejection: { commandType: string; reason: string } | null;
|
|
1053
2022
|
lastEvent: null | Record<string, unknown>;
|
|
1054
2023
|
}
|
|
1055
2024
|
|
|
@@ -1073,19 +2042,67 @@ export interface ConversationConfig {
|
|
|
1073
2042
|
autoRespond?: boolean;
|
|
1074
2043
|
maxHistory?: number;
|
|
1075
2044
|
responseSource?: string;
|
|
2045
|
+
/** Text replies complete when accepted. Speech (default) waits for TTS playout. */
|
|
2046
|
+
responseDelivery?: 'speech' | 'text';
|
|
1076
2047
|
ttsAgency?: string;
|
|
1077
2048
|
interruptionMode?: string;
|
|
2049
|
+
/** Snapshot of module speech settings applied to each utterance. */
|
|
2050
|
+
speechConfig?: TTSConfig;
|
|
2051
|
+
transcriptionConfig?: TranscriptionConfig;
|
|
1078
2052
|
autoListen?: boolean;
|
|
1079
2053
|
detectInterruptions?: boolean;
|
|
2054
|
+
/** Minimum playback time for transcript fallback; sustained audio is accepted immediately. */
|
|
1080
2055
|
minSpeakTime?: number;
|
|
1081
2056
|
allowTranscriptInterruptionFallback?: boolean;
|
|
1082
2057
|
eyeHeadTracking?: EyeHeadTrackingService | unknown;
|
|
1083
2058
|
prosodicService?: unknown;
|
|
1084
2059
|
}
|
|
1085
2060
|
|
|
2061
|
+
/** Context identities are scoped to one Conversation instance. Revisions strictly
|
|
2062
|
+
* increase for replacement and removal. Reset clears the bounded registry. */
|
|
2063
|
+
export interface ConversationContextRef {
|
|
2064
|
+
namespace: string;
|
|
2065
|
+
sourceId: string;
|
|
2066
|
+
revision: number;
|
|
2067
|
+
}
|
|
2068
|
+
export interface ConversationContext extends ConversationContextRef {
|
|
2069
|
+
schemaVersion: 1;
|
|
2070
|
+
/** Plain JSON, depth <= 8 and serialized length <= 8192 UTF-16 code units. */
|
|
2071
|
+
content: unknown;
|
|
2072
|
+
}
|
|
2073
|
+
export type ConversationTurnPurpose = 'explain' | 'ask' | 'clarify' | 'feedback';
|
|
2074
|
+
export interface ConversationRequestedTurn {
|
|
2075
|
+
/** Unique per session; duplicate requests are ignored, including after outcome. */
|
|
2076
|
+
requestId: string;
|
|
2077
|
+
purpose: ConversationTurnPurpose;
|
|
2078
|
+
objective: string;
|
|
2079
|
+
}
|
|
2080
|
+
export interface ConversationSpeechIdentity {
|
|
2081
|
+
turnId: string;
|
|
2082
|
+
requestId?: string;
|
|
2083
|
+
speechId: string;
|
|
2084
|
+
}
|
|
2085
|
+
export interface ConversationTurnOutcome {
|
|
2086
|
+
type: 'conversation.turnOutcome';
|
|
2087
|
+
agency: 'conversation';
|
|
2088
|
+
requestId: string;
|
|
2089
|
+
turnId: string;
|
|
2090
|
+
purpose: ConversationTurnPurpose;
|
|
2091
|
+
contextRefs: ConversationContextRef[];
|
|
2092
|
+
outcome: 'completed' | 'interrupted' | 'cancelled' | 'failed';
|
|
2093
|
+
/** True when playout began; only completed guarantees the whole text played. */
|
|
2094
|
+
spoken: boolean;
|
|
2095
|
+
reason: string;
|
|
2096
|
+
at: number;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
1086
2099
|
export interface ConversationProviderRequest {
|
|
1087
2100
|
requestId: string;
|
|
1088
|
-
|
|
2101
|
+
/** Null for agency-requested dialogue; never fabricated as a user utterance. */
|
|
2102
|
+
text: string | null;
|
|
2103
|
+
requestedTurn?: ConversationRequestedTurn | null;
|
|
2104
|
+
contextRefs?: ConversationContextRef[];
|
|
2105
|
+
contexts?: ConversationContext[];
|
|
1089
2106
|
source: string;
|
|
1090
2107
|
turnId?: string;
|
|
1091
2108
|
history: Array<Record<string, unknown>>;
|
|
@@ -1124,6 +2141,9 @@ export interface ConversationHistoryEntry {
|
|
|
1124
2141
|
source?: string;
|
|
1125
2142
|
at?: number;
|
|
1126
2143
|
turnId?: string | null;
|
|
2144
|
+
requestId?: string | null;
|
|
2145
|
+
contextRefs?: ConversationContextRef[];
|
|
2146
|
+
deliveryStatus?: 'requested' | 'pending' | 'speaking' | 'delivered' | 'interrupted' | 'cancelled' | 'failed';
|
|
1127
2147
|
}
|
|
1128
2148
|
|
|
1129
2149
|
export interface ConversationState {
|
|
@@ -1133,7 +2153,15 @@ export interface ConversationState {
|
|
|
1133
2153
|
turnId: string | null;
|
|
1134
2154
|
history: ConversationHistoryEntry[];
|
|
1135
2155
|
context: Record<string, unknown>;
|
|
2156
|
+
contexts: Record<string, ConversationContext>;
|
|
2157
|
+
contextVersions: Record<string, number>;
|
|
2158
|
+
activeTurn: (Partial<ConversationRequestedTurn> & { turnId: string; contextRefs: ConversationContextRef[]; speechId?: string; responseDelivery: 'speech' | 'text'; spoken: boolean }) | null;
|
|
2159
|
+
seenRequests: string[];
|
|
1136
2160
|
pendingResponse: Record<string, unknown> | null;
|
|
2161
|
+
activeSpeechId: string | null;
|
|
2162
|
+
/** Conversation has requested speech resources that still require release. */
|
|
2163
|
+
speechResourcesRequested: boolean;
|
|
2164
|
+
playbackStartedAt: number | null;
|
|
1137
2165
|
lastProviderError: string | null;
|
|
1138
2166
|
lastUserText: string | null;
|
|
1139
2167
|
lastAgentText: string | null;
|
|
@@ -1154,10 +2182,20 @@ export type ConversationDispatch =
|
|
|
1154
2182
|
| { type: 'start' }
|
|
1155
2183
|
| { type: 'stop'; reason?: string }
|
|
1156
2184
|
| { type: 'reset' }
|
|
1157
|
-
| { type: 'cancel' | 'interrupt'; reason?: string }
|
|
2185
|
+
| { type: 'cancel' | 'interrupt'; reason?: string; requestId?: string }
|
|
2186
|
+
| ({ type: 'context.upsert' } & ConversationContext)
|
|
2187
|
+
| ({ type: 'context.remove' } & ConversationContextRef)
|
|
2188
|
+
| ({ type: 'requestTurn'; contextRefs: ConversationContextRef[] } & ConversationRequestedTurn)
|
|
2189
|
+
| ({ type: 'ttsSpeechStarted' | 'ttsSpeechStopped' | 'ttsSpeechEnded' | 'ttsSpeechFailed'; reason?: string; message?: string } & ConversationSpeechIdentity)
|
|
1158
2190
|
| { type: 'transcript.final' | 'transcriptFinal' | 'userUtterance'; text?: string; transcript?: string; utterance?: string; responseText?: string; agentText?: string; source?: string }
|
|
1159
2191
|
| { type: 'agentUtterance' | 'responseReady'; text?: string; utterance?: string; responseText?: string; agentText?: string; requestId?: string; turnId?: string; source?: string }
|
|
1160
2192
|
| { type: 'providerError'; requestId?: string; turnId?: string; message?: string }
|
|
2193
|
+
| { type: 'listen' | 'pauseListening' | 'flowStart' }
|
|
2194
|
+
| { type: 'audioInterruption' | 'transcriptInterruption'; event?: InterruptionEvent; text?: string }
|
|
2195
|
+
| { type: 'transcript.partial'; text: string }
|
|
2196
|
+
| { type: 'ttsSpeechStarted' | 'ttsSpeechStopped' | 'ttsSpeechEnded'; name?: string }
|
|
2197
|
+
| { type: 'transcriptionStatus'; status: string; reason?: string }
|
|
2198
|
+
| { type: 'ttsError'; message: string }
|
|
1161
2199
|
| { type: 'tts.status'; status?: string };
|
|
1162
2200
|
|
|
1163
2201
|
export interface TranscriptionConfig {
|
|
@@ -1207,6 +2245,7 @@ export interface TranscriptionState {
|
|
|
1207
2245
|
export type TranscriptionDispatch =
|
|
1208
2246
|
| { type: 'configure'; config: TranscriptionConfig }
|
|
1209
2247
|
| { type: 'start' }
|
|
2248
|
+
| { type: 'release' }
|
|
1210
2249
|
| { type: 'stop' | 'cancel'; reason?: string }
|
|
1211
2250
|
| { type: 'reset' }
|
|
1212
2251
|
| { type: 'providerPartial' | 'partialTranscript' | 'providerFinal' | 'finalTranscript'; text?: string; transcript?: string; confidence?: number; source?: string; speaker?: string }
|
|
@@ -1217,6 +2256,7 @@ export type TranscriptionDispatch =
|
|
|
1217
2256
|
|
|
1218
2257
|
export interface CameraContextConfig {
|
|
1219
2258
|
coalesceMs?: number;
|
|
2259
|
+
/** Expiry for streaming owners; defaults to 0 (valid until explicitly invalidated). */
|
|
1220
2260
|
staleAfterMs?: number;
|
|
1221
2261
|
epsilon?: number;
|
|
1222
2262
|
yawWeight?: number;
|
|
@@ -1237,11 +2277,22 @@ export interface PolymerQuaternion {
|
|
|
1237
2277
|
}
|
|
1238
2278
|
|
|
1239
2279
|
export interface CameraContextState {
|
|
2280
|
+
configuration: AgencyConfigurationState;
|
|
2281
|
+
family: 'perception';
|
|
2282
|
+
lastDecision: CameraContextDecision | null;
|
|
2283
|
+
/** Safe bounded inspection projection; full operational snapshots are not redacted. */
|
|
2284
|
+
summary: Pick<CameraContextState,
|
|
2285
|
+
'status' | 'stale' | 'updateCount' | 'publishedCount' | 'lastUpdatedAt' | 'lastPublishedAt' | 'lastDecision'>;
|
|
1240
2286
|
agency: 'cameraContext';
|
|
1241
2287
|
status: string;
|
|
1242
2288
|
cameraPosition: PolymerVector3 | null;
|
|
2289
|
+
cameraQuaternion: PolymerQuaternion;
|
|
1243
2290
|
targetPosition: PolymerVector3 | null;
|
|
2291
|
+
gazeOrigin: PolymerVector3 | null;
|
|
1244
2292
|
modelQuaternion: PolymerQuaternion;
|
|
2293
|
+
verticalFovDegrees: number;
|
|
2294
|
+
aspect: number;
|
|
2295
|
+
gazeGeometryComplete: boolean;
|
|
1245
2296
|
relativeOffset: Required<GazeTarget>;
|
|
1246
2297
|
lastUpdatedAt: number | null;
|
|
1247
2298
|
lastPublishedAt: number | null;
|
|
@@ -1261,14 +2312,145 @@ export type CameraContextDispatch =
|
|
|
1261
2312
|
type: 'updateCamera';
|
|
1262
2313
|
facts?: Record<string, unknown>;
|
|
1263
2314
|
cameraPosition?: PolymerVector3;
|
|
2315
|
+
cameraQuaternion?: PolymerQuaternion;
|
|
1264
2316
|
targetPosition?: PolymerVector3;
|
|
2317
|
+
gazeOrigin?: PolymerVector3;
|
|
2318
|
+
characterEyePosition?: PolymerVector3;
|
|
1265
2319
|
modelQuaternion?: PolymerQuaternion;
|
|
2320
|
+
verticalFovDegrees?: number;
|
|
2321
|
+
aspect?: number;
|
|
1266
2322
|
source?: string;
|
|
1267
2323
|
}
|
|
1268
2324
|
| { type: 'publishCameraFacts' }
|
|
1269
2325
|
| { type: 'invalidateStale'; reason?: string }
|
|
1270
2326
|
| { type: 'reset' };
|
|
1271
2327
|
|
|
2328
|
+
export interface UserPerceptionConfig {
|
|
2329
|
+
enabled?: boolean;
|
|
2330
|
+
/** Package asset by default; may be replaced by a host-controlled URL. */
|
|
2331
|
+
modelAssetPath?: string;
|
|
2332
|
+
/** Package MediaPipe WASM directory by default; may be replaced by a URL. */
|
|
2333
|
+
wasmRoot?: string;
|
|
2334
|
+
/** Package inference worker by default; may be replaced by a worker URL. */
|
|
2335
|
+
workerUrl?: string;
|
|
2336
|
+
delegate?: 'CPU' | 'GPU';
|
|
2337
|
+
maxFaces?: number;
|
|
2338
|
+
maxInferenceFps?: number;
|
|
2339
|
+
minDetectionConfidence?: number;
|
|
2340
|
+
minTrackingConfidence?: number;
|
|
2341
|
+
minPresenceConfidence?: number;
|
|
2342
|
+
/** Retained history over 50ms, from 0 (immediate) through 0.95. Applied to eye-midpoint XY using elapsed time. */
|
|
2343
|
+
smoothing?: number;
|
|
2344
|
+
/** Whether inference pixels are already mirrored. Default false reflects raw webcam X into display-right NDC; a CSS preview does not affect this. */
|
|
2345
|
+
mirrored?: boolean;
|
|
2346
|
+
/** Default true: use the first accepted face as this session's eye-contact origin. False retains absolute webcam-centered coordinates. */
|
|
2347
|
+
centerOnFirstFace?: boolean;
|
|
2348
|
+
faceLossGraceMs?: number;
|
|
2349
|
+
maxRetries?: number;
|
|
2350
|
+
retryBackoffMs?: number;
|
|
2351
|
+
candidatePriority?: number;
|
|
2352
|
+
diagnosticIntervalMs?: number;
|
|
2353
|
+
videoWidth?: number;
|
|
2354
|
+
videoHeight?: number;
|
|
2355
|
+
/** Assumed/calibrated webcam vertical field of view. Default 50 degrees. */
|
|
2356
|
+
viewerVerticalFovDegrees?: number;
|
|
2357
|
+
/** Physical eye-center spacing used only for diagnostic depth estimation. Default 0.063m. */
|
|
2358
|
+
viewerInterpupillaryDistanceMeters?: number;
|
|
2359
|
+
/** Fixed projection depth shared by webcam and mouse tracking. Default 0.8m. */
|
|
2360
|
+
viewerFallbackDepthMeters?: number;
|
|
2361
|
+
/** Lower bound for diagnostic depth only. */
|
|
2362
|
+
viewerMinDepthMeters?: number;
|
|
2363
|
+
/** Upper bound for diagnostic depth only. */
|
|
2364
|
+
viewerMaxDepthMeters?: number;
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
export interface UserPerceptionCameraMetadata {
|
|
2368
|
+
width: number;
|
|
2369
|
+
height: number;
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
export interface UserPerceptionFaceObservation {
|
|
2373
|
+
id: string;
|
|
2374
|
+
confidence?: number;
|
|
2375
|
+
score?: number;
|
|
2376
|
+
bounds: {
|
|
2377
|
+
left: number;
|
|
2378
|
+
top: number;
|
|
2379
|
+
right: number;
|
|
2380
|
+
bottom: number;
|
|
2381
|
+
width: number;
|
|
2382
|
+
height: number;
|
|
2383
|
+
area: number;
|
|
2384
|
+
center: PolymerVector3;
|
|
2385
|
+
};
|
|
2386
|
+
/** Binocular midpoint of the anatomical eye-corner centers, independent of pupil motion. */
|
|
2387
|
+
eyeMidpoint: PolymerVector3;
|
|
2388
|
+
/** Compact separation; z uses MediaPipe's approximate normalized-X depth scale. */
|
|
2389
|
+
interocularDistance?: { x: number; y: number; z?: number; normalized?: number };
|
|
2390
|
+
/** Observational iris offset, not calibrated gaze direction. */
|
|
2391
|
+
irisDirection?: { x: number; y: number } | null;
|
|
2392
|
+
headPose: { yaw: number; pitch: number; roll: number };
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
export interface UserPerceptionState {
|
|
2396
|
+
agency: 'userPerception';
|
|
2397
|
+
status: 'idle' | 'requestingPermission' | 'loadingModel' | 'ready' | 'observing' | 'faceLost' | 'backingOff' | 'stopped' | 'error' | string;
|
|
2398
|
+
active: boolean;
|
|
2399
|
+
visible: boolean;
|
|
2400
|
+
permission: 'unknown' | 'prompt' | 'granted' | 'denied' | string;
|
|
2401
|
+
cameraStatus: string;
|
|
2402
|
+
/** Negotiated/captured dimensions, retained after stop until reset or acquisition. */
|
|
2403
|
+
cameraMetadata: UserPerceptionCameraMetadata | null;
|
|
2404
|
+
modelStatus: string;
|
|
2405
|
+
faceDetected: boolean;
|
|
2406
|
+
selectedFaceConfidence: number | null;
|
|
2407
|
+
target: Required<GazeTarget>;
|
|
2408
|
+
/** Fixed display-right/up normalized eye-midpoint offset for this activation; never persisted across sessions. */
|
|
2409
|
+
eyeContactReference: { x: number; y: number } | null;
|
|
2410
|
+
lastObservationAt: number | null;
|
|
2411
|
+
lastAcceptedAt: number | null;
|
|
2412
|
+
lastDiagnosticAt: number | null;
|
|
2413
|
+
lastCameraFact: Record<string, unknown> | null;
|
|
2414
|
+
lastObservation: Record<string, unknown> | null;
|
|
2415
|
+
lastError: { message: string; phase: string; retrying: boolean; at: number } | null;
|
|
2416
|
+
lastPlan: Record<string, unknown> | null;
|
|
2417
|
+
lastEvent: Record<string, unknown> | null;
|
|
2418
|
+
retryCount: number;
|
|
2419
|
+
capturedFrameCount: number;
|
|
2420
|
+
inferenceCount: number;
|
|
2421
|
+
acceptedCount: number;
|
|
2422
|
+
rejectedCount: number;
|
|
2423
|
+
droppedFrameCount: number;
|
|
2424
|
+
faceLostCount: number;
|
|
2425
|
+
config: Required<UserPerceptionConfig>;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
export type UserPerceptionDispatch =
|
|
2429
|
+
| { type: 'configure' | 'userPerception.configure'; config: UserPerceptionConfig }
|
|
2430
|
+
| { type: 'start' | 'userPerception.start' }
|
|
2431
|
+
| { type: 'stop' | 'userPerception.stop'; reason?: string }
|
|
2432
|
+
| { type: 'reset' | 'userPerception.reset' }
|
|
2433
|
+
| { type: 'recenter' | 'userPerception.recenter' }
|
|
2434
|
+
| Extract<PolymerDomainEvent, { type: 'camera.fact' | 'camera.stale' }>;
|
|
2435
|
+
|
|
2436
|
+
/** Injectable browser boundary for deterministic tests and alternate hosts. */
|
|
2437
|
+
export interface UserPerceptionRuntime {
|
|
2438
|
+
acquireCamera?(config: Required<UserPerceptionConfig>): unknown | Promise<unknown>;
|
|
2439
|
+
releaseCamera?(handle: unknown): void;
|
|
2440
|
+
createWorker?(url: string): Worker;
|
|
2441
|
+
loadModel?(config: Required<UserPerceptionConfig>): unknown | Promise<unknown>;
|
|
2442
|
+
observe?(config: Required<UserPerceptionConfig>, observedAt: number, requestId: string): {
|
|
2443
|
+
observedAt: number;
|
|
2444
|
+
faces: UserPerceptionFaceObservation[];
|
|
2445
|
+
cameraMetadata?: UserPerceptionCameraMetadata;
|
|
2446
|
+
} | Promise<{
|
|
2447
|
+
observedAt: number;
|
|
2448
|
+
faces: UserPerceptionFaceObservation[];
|
|
2449
|
+
cameraMetadata?: UserPerceptionCameraMetadata;
|
|
2450
|
+
}>;
|
|
2451
|
+
isDocumentVisible?(): boolean;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
1272
2454
|
export type LipSyncSchedulerQueueEntry =
|
|
1273
2455
|
| {
|
|
1274
2456
|
type: 'scheduleAnimation';
|
|
@@ -1328,7 +2510,7 @@ export type ProsodicSchedulerQueueEntry =
|
|
|
1328
2510
|
|
|
1329
2511
|
export type TTSSchedulerQueueEntry =
|
|
1330
2512
|
| {
|
|
1331
|
-
type: 'webSpeechStartFallback';
|
|
2513
|
+
type: 'webSpeechStartFallback' | 'webSpeechBoundaryWatchdog' | 'ttsCompletionWatchdog';
|
|
1332
2514
|
agency: 'tts';
|
|
1333
2515
|
sessionId: number;
|
|
1334
2516
|
delayMs: number;
|
|
@@ -1428,6 +2610,11 @@ export interface GestureConfig {
|
|
|
1428
2610
|
gestureEmojiMappings?: Record<string, string>;
|
|
1429
2611
|
}
|
|
1430
2612
|
|
|
2613
|
+
export interface GestureOptions extends GestureConfig {
|
|
2614
|
+
/** Private constructor-only clock; never authored in society data. */
|
|
2615
|
+
now?: () => number;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
1431
2618
|
export interface GestureGoal {
|
|
1432
2619
|
gestureId?: string;
|
|
1433
2620
|
id?: string;
|
|
@@ -1468,6 +2655,10 @@ export interface GestureActiveSnippet {
|
|
|
1468
2655
|
}
|
|
1469
2656
|
|
|
1470
2657
|
export interface GestureState {
|
|
2658
|
+
configuration: AgencyConfigurationState;
|
|
2659
|
+
lastDecision: GestureDecision | null;
|
|
2660
|
+
lifecycle: 'active' | 'disposed';
|
|
2661
|
+
rejectedCommandCount: number;
|
|
1471
2662
|
agency: 'gesture';
|
|
1472
2663
|
gestures: string[];
|
|
1473
2664
|
gestureCount: number;
|
|
@@ -1506,6 +2697,14 @@ export interface PolymerInputStream<TCommand> extends PolymerStream<{ type: 'com
|
|
|
1506
2697
|
|
|
1507
2698
|
|
|
1508
2699
|
export type PolymerDomainEvent =
|
|
2700
|
+
| { type: 'gaze.attention'; agency: 'gaze'; attention: GazeAttentionState }
|
|
2701
|
+
| { type: 'animation.requestObserveGaze'; agency: 'eyeHeadTracking'; requestId: string; sessionId: string; worldTarget: PolymerVector3 | null; timeoutMs: number; toleranceDeg: number }
|
|
2702
|
+
| { type: 'animation.requestCancelGazeObservation'; agency: 'eyeHeadTracking'; requestId: string | null }
|
|
2703
|
+
| { type: 'animation.gazeFeedback'; agency: 'animation'; requestId: string; status: 'observed' | 'unavailable'; reason: string; angularErrorDeg?: number; sampleSequence?: number; observedAt?: number; bindingGeneration?: number }
|
|
2704
|
+
| { type: 'gaze.configurationChanged'; agency: 'gaze'; configuration: AgencyConfigurationState; configure: GazeEditableConfiguration }
|
|
2705
|
+
| { type: 'gaze.decision'; agency: 'gaze'; decision: GazeDecision }
|
|
2706
|
+
| { type: 'gestureDecision'; agency: 'gesture'; decision: GestureDecision }
|
|
2707
|
+
| { type: 'gestureCommandRejected'; agency: 'gesture'; commandType: string; reason: 'revision-exhausted' }
|
|
1509
2708
|
| {
|
|
1510
2709
|
/** Diagnostic telemetry emitted after a graph route dispatch succeeds. */
|
|
1511
2710
|
type: 'society.routeActivated';
|
|
@@ -1623,18 +2822,24 @@ export type PolymerDomainEvent =
|
|
|
1623
2822
|
| GazeLookRequest
|
|
1624
2823
|
| GazeResetRequest
|
|
1625
2824
|
| GazeCancelRequest
|
|
1626
|
-
| { type: 'camera.status'; agency: 'cameraContext'; status: string; stale: boolean; reason?: string; at: number }
|
|
2825
|
+
| { type: 'camera.status'; agency: 'cameraContext'; status: string; stale: boolean; reason?: string; at: number; configurationRevision: number }
|
|
1627
2826
|
| {
|
|
1628
2827
|
type: 'camera.fact';
|
|
1629
2828
|
agency: 'cameraContext';
|
|
2829
|
+
configurationRevision: number;
|
|
1630
2830
|
kind: 'camera.relative';
|
|
1631
2831
|
sequence: number;
|
|
1632
2832
|
source: string;
|
|
1633
2833
|
observedAt: number;
|
|
1634
2834
|
publishedAt: number;
|
|
1635
2835
|
cameraPosition: Record<string, number>;
|
|
2836
|
+
cameraQuaternion: Record<string, number>;
|
|
1636
2837
|
targetPosition: Record<string, number>;
|
|
2838
|
+
gazeOrigin: Record<string, number>;
|
|
1637
2839
|
modelQuaternion: Record<string, number>;
|
|
2840
|
+
verticalFovDegrees: number;
|
|
2841
|
+
aspect: number;
|
|
2842
|
+
gazeGeometryComplete: boolean;
|
|
1638
2843
|
relativeOffset: Required<GazeTarget>;
|
|
1639
2844
|
stale: false;
|
|
1640
2845
|
}
|
|
@@ -1648,6 +2853,55 @@ export type PolymerDomainEvent =
|
|
|
1648
2853
|
lastObservedAt?: number;
|
|
1649
2854
|
lastRelativeOffset?: Required<GazeTarget>;
|
|
1650
2855
|
}
|
|
2856
|
+
| {
|
|
2857
|
+
type: 'userPerception.status';
|
|
2858
|
+
agency: 'userPerception';
|
|
2859
|
+
status: string;
|
|
2860
|
+
active: boolean;
|
|
2861
|
+
visible: boolean;
|
|
2862
|
+
permission: string;
|
|
2863
|
+
cameraStatus: string;
|
|
2864
|
+
cameraMetadata?: UserPerceptionCameraMetadata | null;
|
|
2865
|
+
modelStatus: string;
|
|
2866
|
+
faceDetected: boolean;
|
|
2867
|
+
reason?: string;
|
|
2868
|
+
at: number;
|
|
2869
|
+
}
|
|
2870
|
+
| {
|
|
2871
|
+
type: 'attention.fact';
|
|
2872
|
+
agency: 'userPerception';
|
|
2873
|
+
targetAgency: 'gaze';
|
|
2874
|
+
source: 'userPerception';
|
|
2875
|
+
label: string;
|
|
2876
|
+
observedAt: number;
|
|
2877
|
+
confidence?: number | null;
|
|
2878
|
+
priority: number;
|
|
2879
|
+
target: Required<GazeTarget>;
|
|
2880
|
+
screenTarget: Required<GazeTarget>;
|
|
2881
|
+
targetSpace: 'screen.ndc';
|
|
2882
|
+
viewerTarget: Required<GazeTarget>;
|
|
2883
|
+
viewerTargetSpace: 'webcam.viewer';
|
|
2884
|
+
viewerVerticalFovDegrees: number;
|
|
2885
|
+
viewerAspect: number;
|
|
2886
|
+
cameraMetadata?: UserPerceptionCameraMetadata | null;
|
|
2887
|
+
rawViewerTarget: Required<GazeTarget>;
|
|
2888
|
+
options?: GazeApplyOptions;
|
|
2889
|
+
rawTarget: Required<GazeTarget>;
|
|
2890
|
+
face: Pick<UserPerceptionFaceObservation, 'id' | 'bounds' | 'eyeMidpoint' | 'interocularDistance' | 'headPose' | 'irisDirection'>;
|
|
2891
|
+
}
|
|
2892
|
+
| {
|
|
2893
|
+
type: 'userPerception.observation';
|
|
2894
|
+
agency: 'userPerception';
|
|
2895
|
+
observedAt: number;
|
|
2896
|
+
confidence?: number | null;
|
|
2897
|
+
target: Required<GazeTarget>;
|
|
2898
|
+
viewerTarget: Required<GazeTarget>;
|
|
2899
|
+
cameraMetadata?: UserPerceptionCameraMetadata | null;
|
|
2900
|
+
face: Record<string, unknown>;
|
|
2901
|
+
at: number;
|
|
2902
|
+
}
|
|
2903
|
+
| { type: 'userPerception.faceLost'; agency: 'userPerception'; reason: string; lastSeenAt?: number; at: number }
|
|
2904
|
+
| { type: 'userPerception.ignored'; agency: 'userPerception'; reason: string; commandType?: string; at: number }
|
|
1651
2905
|
| {
|
|
1652
2906
|
type: 'eyeHeadTracking.status';
|
|
1653
2907
|
agency: 'eyeHeadTracking';
|
|
@@ -1711,9 +2965,10 @@ export type PolymerDomainEvent =
|
|
|
1711
2965
|
status?: 'checking' | 'ready' | 'error' | string;
|
|
1712
2966
|
message?: string;
|
|
1713
2967
|
}
|
|
1714
|
-
| { type: 'ttsSpeechStarted'; agency: 'tts'; engine: string; name: string; startedAt: number }
|
|
1715
|
-
| { type: 'ttsSpeechStopped'; agency: 'tts'; reason: string; stoppedAt: number }
|
|
1716
|
-
| { type: 'ttsSpeechEnded'; agency: 'tts'; endedAt: number }
|
|
2968
|
+
| ({ type: 'ttsSpeechStarted'; agency: 'tts'; engine: string; name: string; text?: string; startedAt: number } & Partial<ConversationSpeechIdentity>)
|
|
2969
|
+
| ({ type: 'ttsSpeechStopped'; agency: 'tts'; reason: string; name?: string | null; stoppedAt: number } & Partial<ConversationSpeechIdentity>)
|
|
2970
|
+
| ({ type: 'ttsSpeechEnded'; agency: 'tts'; name?: string | null; endedAt: number } & Partial<ConversationSpeechIdentity>)
|
|
2971
|
+
| ({ type: 'ttsSpeechFailed'; agency: 'tts'; name?: string | null; message: string } & Partial<ConversationSpeechIdentity>)
|
|
1717
2972
|
| { type: 'ttsPlaybackReferenceChanged'; agency: 'tts'; available: boolean; at: number }
|
|
1718
2973
|
| {
|
|
1719
2974
|
type: 'ttsWordBoundary';
|
|
@@ -1724,11 +2979,17 @@ export type PolymerDomainEvent =
|
|
|
1724
2979
|
hostElapsedSec?: number;
|
|
1725
2980
|
}
|
|
1726
2981
|
| { type: 'lipSync.command'; agency: 'tts'; command: LipSyncDispatch }
|
|
2982
|
+
| { type: 'conversation.ttsReleaseReferenceRequested'; agency: 'conversation'; command: TTSDispatch }
|
|
2983
|
+
| { type: 'conversation.ttsConfigureRequested'; agency: 'conversation'; command: TTSDispatch }
|
|
2984
|
+
| { type: 'conversation.transcriptionRequested'; agency: 'conversation'; command: TranscriptionDispatch }
|
|
2985
|
+
| { type: 'conversation.transcript'; agency: 'conversation'; text: string; isFinal: boolean; isInterruption: boolean; at: number }
|
|
1727
2986
|
| { type: 'conversation.status'; agency: 'conversation'; status: string; turnId?: string; reason?: string; at: number }
|
|
1728
2987
|
| { type: 'conversation.userUtterance'; agency: 'conversation'; text: string; source: string; turnId?: string; at: number }
|
|
1729
|
-
| { type: 'conversation.requestResponse'; agency: 'conversation'; targetAgency: string
|
|
2988
|
+
| ({ type: 'conversation.requestResponse'; agency: 'conversation'; targetAgency: string } & ConversationProviderRequest)
|
|
2989
|
+
| ({ type: 'conversation.turnRequested'; agency: 'conversation'; turnId: string; contextRefs: ConversationContextRef[]; spoken: false; at: number } & ConversationRequestedTurn)
|
|
2990
|
+
| ConversationTurnOutcome
|
|
1730
2991
|
| { type: 'conversation.providerError'; agency: 'conversation'; requestId: string; turnId?: string; message: string; at: number }
|
|
1731
|
-
| { type: 'conversation.agentUtterance'; agency: 'conversation'; text: string; at: number }
|
|
2992
|
+
| { type: 'conversation.agentUtterance'; agency: 'conversation'; text: string; source: string; turnId: string; at: number }
|
|
1732
2993
|
| { type: 'conversation.cancelRequested'; agency: 'conversation'; targetAgency: string; reason: string; turnId?: string; at: number }
|
|
1733
2994
|
| { type: 'conversation.ignored'; agency: 'conversation'; reason: string; requestId?: string; turnId?: string; at: number }
|
|
1734
2995
|
| { type: 'tts.requestSpeak'; agency: 'conversation'; targetAgency: string; requestId: string; text: string; source: string; turnId?: string; command: TTSDispatch; requestedAt: number }
|
|
@@ -1758,6 +3019,8 @@ export type PolymerDomainEvent =
|
|
|
1758
3019
|
| { type: 'gestureRemoved'; agency: 'gesture'; name: string; reason: string; removedAt: number }
|
|
1759
3020
|
| { type: 'prosodicPlanCreated'; agency: 'prosodic'; plan: Record<string, unknown> }
|
|
1760
3021
|
| { type: 'prosodicConfigChanged'; agency: 'prosodic'; state: ProsodicState }
|
|
3022
|
+
| { type: 'prosodicDecision'; agency: 'prosodic'; decision: ProsodicDecision }
|
|
3023
|
+
| { type: 'prosodicCommandRejected'; agency: 'prosodic'; rejection: { commandType: string; reason: string } }
|
|
1761
3024
|
| { type: 'prosodicSpeechStarted'; agency: 'prosodic'; name?: string; startedAt: number }
|
|
1762
3025
|
| { type: 'prosodicWordBoundary'; agency: 'prosodic'; word?: string; wordIndex: number; observedAt: number }
|
|
1763
3026
|
| {
|
|
@@ -1770,7 +3033,7 @@ export type PolymerDomainEvent =
|
|
|
1770
3033
|
scheduledAt: number;
|
|
1771
3034
|
}
|
|
1772
3035
|
| { type: 'prosodicStopped'; agency: 'prosodic'; reason: string; stoppedAt: number }
|
|
1773
|
-
| { type: string; agency: 'conversation' | 'transcription' | 'cameraContext'; [key: string]: unknown }
|
|
3036
|
+
| { type: string; agency: 'conversation' | 'transcription' | 'cameraContext' | 'userPerception'; [key: string]: unknown }
|
|
1774
3037
|
| {
|
|
1775
3038
|
type: 'ready';
|
|
1776
3039
|
agency:
|
|
@@ -1785,7 +3048,8 @@ export type PolymerDomainEvent =
|
|
|
1785
3048
|
| 'prosodic'
|
|
1786
3049
|
| 'conversation'
|
|
1787
3050
|
| 'transcription'
|
|
1788
|
-
| 'cameraContext'
|
|
3051
|
+
| 'cameraContext'
|
|
3052
|
+
| 'userPerception';
|
|
1789
3053
|
}
|
|
1790
3054
|
| { type: 'error'; agency: string; message: string };
|
|
1791
3055
|
|
|
@@ -1838,6 +3102,8 @@ export interface AnimationAgency {
|
|
|
1838
3102
|
}
|
|
1839
3103
|
|
|
1840
3104
|
export interface GazeAgency {
|
|
3105
|
+
/** Applies between decisions; pending requests retain their accepted policy. */
|
|
3106
|
+
applyConfiguration(update: { revision: number; configure: GazeEditableConfiguration }): AgencyConfigurationReceipt;
|
|
1841
3107
|
input: PolymerInputStream<GazeDispatch>;
|
|
1842
3108
|
events: PolymerStream<PolymerDomainEvent>;
|
|
1843
3109
|
dispatch(command: GazeDispatch): void;
|
|
@@ -1934,6 +3200,8 @@ export interface TTSAgency {
|
|
|
1934
3200
|
}
|
|
1935
3201
|
|
|
1936
3202
|
export interface GestureAgency {
|
|
3203
|
+
/** Applies between decisions; already scheduled snippets are unchanged. */
|
|
3204
|
+
applyConfiguration(update: { revision: number; configure: GestureEditableConfiguration }): AgencyConfigurationReceipt;
|
|
1937
3205
|
input: PolymerInputStream<GestureDispatch>;
|
|
1938
3206
|
events: PolymerStream<PolymerDomainEvent>;
|
|
1939
3207
|
dispatch(command: GestureDispatch): void;
|
|
@@ -1969,6 +3237,14 @@ export interface ProsodicAgency {
|
|
|
1969
3237
|
/** Compatibility alias for events. Prefer subscribeEvents. */
|
|
1970
3238
|
subscribeStatus(listener: (event: PolymerStatusEvent) => void): () => void;
|
|
1971
3239
|
configure(config: ProsodicConfig): void;
|
|
3240
|
+
/** Atomic between decisions. Invalid/stale updates do not consume a revision.
|
|
3241
|
+
* Existing scheduled work retains its original policy. Reentrant calls during
|
|
3242
|
+
* a decision or configuration notification are rejected; retry at a boundary.
|
|
3243
|
+
*/
|
|
3244
|
+
applyConfiguration(update: {
|
|
3245
|
+
revision: number;
|
|
3246
|
+
configure: ProsodicEditableConfiguration;
|
|
3247
|
+
}): ProsodicConfigurationReceipt;
|
|
1972
3248
|
speechStarted(name?: string): void;
|
|
1973
3249
|
wordBoundary(word: string, wordIndex?: number): void;
|
|
1974
3250
|
blinkFast(): void;
|
|
@@ -1986,6 +3262,7 @@ export interface ConversationAgency {
|
|
|
1986
3262
|
subscribeEvents(listener: (event: PolymerDomainEvent) => void): () => void;
|
|
1987
3263
|
subscribe(listener: (event: PolymerStatusEvent) => void): () => void;
|
|
1988
3264
|
subscribeStatus(listener: (event: PolymerStatusEvent) => void): () => void;
|
|
3265
|
+
startFlow(factory: (context: ConversationFlowContext) => ConversationFlow): void;
|
|
1989
3266
|
start(): void;
|
|
1990
3267
|
stop(): void;
|
|
1991
3268
|
reset(): void;
|
|
@@ -2013,6 +3290,8 @@ export interface TranscriptionAgency {
|
|
|
2013
3290
|
}
|
|
2014
3291
|
|
|
2015
3292
|
export interface CameraContextAgency {
|
|
3293
|
+
/** Applies to new observations; already pending facts retain their policy. */
|
|
3294
|
+
applyConfiguration(update: { revision: number; configure: CameraContextEditableConfiguration }): AgencyConfigurationReceipt;
|
|
2016
3295
|
input: PolymerInputStream<CameraContextDispatch>;
|
|
2017
3296
|
events: PolymerStream<PolymerDomainEvent>;
|
|
2018
3297
|
dispatch(command: CameraContextDispatch): void;
|
|
@@ -2028,12 +3307,32 @@ export interface CameraContextAgency {
|
|
|
2028
3307
|
dispose(): void;
|
|
2029
3308
|
}
|
|
2030
3309
|
|
|
3310
|
+
export interface UserPerceptionAgency {
|
|
3311
|
+
input: PolymerInputStream<UserPerceptionDispatch>;
|
|
3312
|
+
events: PolymerStream<PolymerDomainEvent>;
|
|
3313
|
+
dispatch(command: UserPerceptionDispatch): void;
|
|
3314
|
+
snapshot(): UserPerceptionState;
|
|
3315
|
+
subscribeInput(listener: (event: { type: 'command'; agency: 'userPerception'; command: UserPerceptionDispatch }) => void): () => void;
|
|
3316
|
+
subscribeEvents(listener: (event: PolymerDomainEvent) => void): () => void;
|
|
3317
|
+
subscribe(listener: (event: PolymerStatusEvent) => void): () => void;
|
|
3318
|
+
subscribeStatus(listener: (event: PolymerStatusEvent) => void): () => void;
|
|
3319
|
+
configure(config: UserPerceptionConfig): void;
|
|
3320
|
+
start(): void;
|
|
3321
|
+
stop(): void;
|
|
3322
|
+
/** Reset eye contact to the current face, or the next accepted face if none is visible. */
|
|
3323
|
+
recenter(): void;
|
|
3324
|
+
reset(): void;
|
|
3325
|
+
queue(): Array<Record<string, unknown>>;
|
|
3326
|
+
dispose(): void;
|
|
3327
|
+
}
|
|
3328
|
+
|
|
2031
3329
|
export interface CharacterAgencySnapshot {
|
|
2032
3330
|
blink: BlinkState;
|
|
2033
3331
|
gaze: GazeState;
|
|
2034
3332
|
eyeHeadTracking: EyeHeadTrackingState;
|
|
2035
3333
|
gesture: GestureState;
|
|
2036
3334
|
cameraContext: CameraContextState;
|
|
3335
|
+
userPerception: UserPerceptionState;
|
|
2037
3336
|
transcription: TranscriptionState;
|
|
2038
3337
|
conversation: ConversationState;
|
|
2039
3338
|
tts: TTSState;
|
|
@@ -2049,6 +3348,7 @@ export type CharacterAgencyDispatch =
|
|
|
2049
3348
|
| { agency: 'eyeHeadTracking'; command: EyeHeadTrackingDispatch }
|
|
2050
3349
|
| { agency: 'gesture'; command: GestureDispatch }
|
|
2051
3350
|
| { agency: 'cameraContext'; command: CameraContextDispatch }
|
|
3351
|
+
| { agency: 'userPerception'; command: UserPerceptionDispatch }
|
|
2052
3352
|
| { agency: 'transcription'; command: TranscriptionDispatch }
|
|
2053
3353
|
| { agency: 'conversation'; command: ConversationDispatch }
|
|
2054
3354
|
| { agency: 'tts'; command: TTSDispatch }
|
|
@@ -2062,7 +3362,10 @@ export interface CharacterAgencies {
|
|
|
2062
3362
|
readonly agencySociety: AgencySociety;
|
|
2063
3363
|
dispatch(message: CharacterAgencyDispatch): void;
|
|
2064
3364
|
snapshot(): CharacterAgencySnapshot;
|
|
2065
|
-
/** Replace
|
|
3365
|
+
/** Replace route admission; Prosodic quiesces before disabling. Nested updates
|
|
3366
|
+
* or re-enable during cleanup return the current society without applying.
|
|
3367
|
+
* Does not overwrite agency-local configure/priors values.
|
|
3368
|
+
*/
|
|
2066
3369
|
updateSocietyRouting(society: AgencySociety): AgencySociety;
|
|
2067
3370
|
agency(name: 'animation'): AnimationAgency;
|
|
2068
3371
|
agency(name: 'blink'): BlinkAgency | null;
|
|
@@ -2070,6 +3373,7 @@ export interface CharacterAgencies {
|
|
|
2070
3373
|
agency(name: 'eyeHeadTracking'): EyeHeadTrackingAgency | null;
|
|
2071
3374
|
agency(name: 'gesture'): GestureAgency | null;
|
|
2072
3375
|
agency(name: 'cameraContext'): CameraContextAgency | null;
|
|
3376
|
+
agency(name: 'userPerception'): UserPerceptionAgency | null;
|
|
2073
3377
|
agency(name: 'transcription'): TranscriptionAgency;
|
|
2074
3378
|
agency(name: 'conversation'): ConversationAgency;
|
|
2075
3379
|
agency(name: 'tts'): TTSAgency;
|
|
@@ -2123,6 +3427,7 @@ export interface AIExpressionSnippetMetadata {
|
|
|
2123
3427
|
}
|
|
2124
3428
|
|
|
2125
3429
|
export interface Snippet {
|
|
3430
|
+
semanticAnimation?: SemanticAnimation;
|
|
2126
3431
|
name?: string;
|
|
2127
3432
|
au?: Array<{ id: string | number; t?: number; v?: number; time?: number; intensity?: number; inherit?: boolean }>;
|
|
2128
3433
|
viseme?: Array<{ key: string | number; t?: number; v?: number; time?: number; intensity?: number; inherit?: boolean }>;
|
|
@@ -2131,12 +3436,17 @@ export interface Snippet {
|
|
|
2131
3436
|
isPlaying?: boolean;
|
|
2132
3437
|
loop?: boolean;
|
|
2133
3438
|
maxTime?: number;
|
|
3439
|
+
cleanupMaxTime?: number;
|
|
2134
3440
|
duration?: number;
|
|
2135
3441
|
snippetCategory?: 'auSnippet' | 'visemeSnippet' | 'eyeHeadTracking' | 'combined' | 'default' | string;
|
|
2136
3442
|
snippetPriority?: number;
|
|
2137
3443
|
snippetPlaybackRate?: number;
|
|
2138
3444
|
snippetIntensityScale?: number;
|
|
2139
3445
|
snippetBlendMode?: 'replace' | 'additive';
|
|
3446
|
+
/** Neutral reference sample for converting a clip to additive rotation. */
|
|
3447
|
+
additiveReferenceTimeSec?: number;
|
|
3448
|
+
/** Stable order for zero-fade, once-only additive controls, even after other clips are removed. */
|
|
3449
|
+
additiveCompositionOrder?: number;
|
|
2140
3450
|
snippetJawScale?: number;
|
|
2141
3451
|
autoVisemeJaw?: boolean;
|
|
2142
3452
|
snippetBalance?: number;
|
|
@@ -2202,10 +3512,10 @@ export interface SnippetUIState {
|
|
|
2202
3512
|
}
|
|
2203
3513
|
|
|
2204
3514
|
export interface BakedClipChannelInfo {
|
|
2205
|
-
channel:
|
|
3515
|
+
channel: BakedClipChannel;
|
|
2206
3516
|
trackCount: number;
|
|
2207
3517
|
playable: boolean;
|
|
2208
|
-
blendMode?:
|
|
3518
|
+
blendMode?: AnimationBlendMode;
|
|
2209
3519
|
}
|
|
2210
3520
|
|
|
2211
3521
|
export interface BakedClipInfo {
|
|
@@ -2222,7 +3532,6 @@ export interface BakedAnimationUIState {
|
|
|
2222
3532
|
duration: number;
|
|
2223
3533
|
speed: number;
|
|
2224
3534
|
playbackRate: number;
|
|
2225
|
-
weight: number;
|
|
2226
3535
|
intensityScale: number;
|
|
2227
3536
|
isPlaying: boolean;
|
|
2228
3537
|
isPaused: boolean;
|
|
@@ -2319,7 +3628,7 @@ export interface AnimationService {
|
|
|
2319
3628
|
bakedAnimationState$(clipName: string): AnimationObservable<BakedAnimationUIState | null>;
|
|
2320
3629
|
loadFromJSON(data: Snippet | NormalizedSnippet): string;
|
|
2321
3630
|
updateSnippet(data: Snippet | NormalizedSnippet): string;
|
|
2322
|
-
schedule(data: Snippet | NormalizedSnippet, opts?: { startInSec?: number; startAtSec?: number; offsetSec?: number; priority?: number; autoPlay?: boolean }): string;
|
|
3631
|
+
schedule(data: Snippet | NormalizedSnippet, opts?: { startInSec?: number; startAtSec?: number; offsetSec?: number; priority?: number; autoPlay?: boolean; loop?: boolean; loopMode?: MixerLoopMode }): string;
|
|
2323
3632
|
remove(name: string): void;
|
|
2324
3633
|
play(): void;
|
|
2325
3634
|
pause(): void;
|
|
@@ -2357,6 +3666,8 @@ export interface AnimationService {
|
|
|
2357
3666
|
pauseBakedAnimation(clipName: string): void;
|
|
2358
3667
|
resumeBakedAnimation(clipName: string): void;
|
|
2359
3668
|
setBakedAnimationSpeed(clipName: string, speed: number): void;
|
|
3669
|
+
setBakedAnimationIntensity(clipName: string, intensity: number): void;
|
|
3670
|
+
/** @deprecated Use setBakedAnimationIntensity. */
|
|
2360
3671
|
setBakedAnimationWeight(clipName: string, weight: number): void;
|
|
2361
3672
|
setBakedAnimationLoop(clipName: string, loop: boolean): void;
|
|
2362
3673
|
setBakedAnimationLoopMode(clipName: string, mode: MixerLoopMode): void;
|
|
@@ -2499,9 +3810,17 @@ export interface ConversationCallbacks {
|
|
|
2499
3810
|
}
|
|
2500
3811
|
|
|
2501
3812
|
export type ConversationFlow = Generator<string | Promise<string>, string | void, string>;
|
|
3813
|
+
export interface ConversationFlowContext {
|
|
3814
|
+
/** Current request signal. Capture before async work and check before applying results. */
|
|
3815
|
+
readonly signal: AbortSignal;
|
|
3816
|
+
}
|
|
2502
3817
|
|
|
2503
3818
|
export interface ConversationService {
|
|
2504
|
-
start(flowGenerator: () => ConversationFlow): void;
|
|
3819
|
+
start(flowGenerator: (context: ConversationFlowContext) => ConversationFlow): void;
|
|
3820
|
+
listen(): void;
|
|
3821
|
+
pauseListening(): void;
|
|
3822
|
+
interrupt(reason?: string): void;
|
|
3823
|
+
updateConfig(config: Partial<ConversationConfig>): void;
|
|
2505
3824
|
stop(): void;
|
|
2506
3825
|
getState(): {
|
|
2507
3826
|
state: ConversationStateName;
|
|
@@ -2542,9 +3861,14 @@ export const playingBakedAnimations$: AnimationObservable<BakedAnimationUIState[
|
|
|
2542
3861
|
export const bakedAnimationProgress$: AnimationObservable<AnimationEvent>;
|
|
2543
3862
|
/** @deprecated Use AnimationService.bakedAnimationState$. */
|
|
2544
3863
|
export function bakedAnimationState$(clipName: string): AnimationObservable<BakedAnimationUIState | null>;
|
|
2545
|
-
export function createAnimationService(
|
|
3864
|
+
export function createAnimationService(
|
|
3865
|
+
engine: Embody | EmbodyRuntime,
|
|
3866
|
+
options?: { agency?: AnimationAgency },
|
|
3867
|
+
): AnimationService;
|
|
2546
3868
|
export function createEyeHeadTrackingService(config?: EyeHeadTrackingConfig, callbacks?: EyeHeadTrackingCallbacks): EyeHeadTrackingService;
|
|
2547
3869
|
export function createTranscriptionService(config?: TranscriptionConfig, callbacks?: TranscriptionCallbacks): TranscriptionService;
|
|
3870
|
+
export function createCharacterConversationService(agencies: CharacterAgencies, config?: ConversationConfig, callbacks?: ConversationCallbacks): ConversationService;
|
|
3871
|
+
/** @deprecated Character hosts should use createCharacterConversationService. */
|
|
2548
3872
|
export function createConversationService(tts: { speak(text: string): Promise<unknown>; stop(): void }, transcription: TranscriptionService, config?: ConversationConfig, callbacks?: ConversationCallbacks): ConversationService;
|
|
2549
3873
|
export const DEFAULT_HAIR_PHYSICS_ENABLED: boolean;
|
|
2550
3874
|
export const DEFAULT_AGENCY_SOCIETY: AgencySociety;
|
|
@@ -2575,6 +3899,8 @@ export interface AgencySocietyEdge {
|
|
|
2575
3899
|
enabled?: boolean;
|
|
2576
3900
|
credit?: number;
|
|
2577
3901
|
match?: Record<string, unknown>;
|
|
3902
|
+
/** Installed cleanup metadata. Setting this on a custom edge grants no bypass. */
|
|
3903
|
+
delivery?: 'cleanup';
|
|
2578
3904
|
}
|
|
2579
3905
|
|
|
2580
3906
|
export interface AgencySocietyKLine {
|
|
@@ -2602,30 +3928,405 @@ export interface AgencySociety {
|
|
|
2602
3928
|
|
|
2603
3929
|
export function createBlinkAgency(config?: BlinkAgencyConfig): BlinkAgency;
|
|
2604
3930
|
export function createAnimationAgency(config?: AnimationAgencyConfig): AnimationAgency;
|
|
2605
|
-
export function createGazeAgency(config?: GazeConfig): GazeAgency;
|
|
3931
|
+
export function createGazeAgency(config?: GazeConfig, runtime?: EmbodyGazeRuntime): GazeAgency;
|
|
2606
3932
|
export function createEyeHeadTrackingAgency(config?: EyeHeadTrackingConfig): EyeHeadTrackingAgency;
|
|
2607
3933
|
export function createLipSyncAgency(config?: LipSyncConfig, runtime?: LipSyncRuntime): LipSyncAgency;
|
|
2608
3934
|
export function createTTSAgency(config?: TTSConfig): TTSAgency;
|
|
2609
|
-
export function createGestureAgency(config?:
|
|
2610
|
-
export function
|
|
3935
|
+
export function createGestureAgency(config?: GestureOptions): GestureAgency;
|
|
3936
|
+
export function getProsodicDefinition(): ProsodicDefinition;
|
|
3937
|
+
export function getGestureDefinition(): GestureDefinition;
|
|
3938
|
+
export function getGazeDefinition(): GazeDefinition;
|
|
3939
|
+
export function getCameraContextDefinition(): CameraContextDefinition;
|
|
3940
|
+
export function createProsodicAgency(config?: ProsodicOptions): ProsodicAgency;
|
|
2611
3941
|
export function createConversationAgency(config?: ConversationAgencyConfig): ConversationAgency;
|
|
2612
3942
|
export function createTranscriptionAgency(config?: TranscriptionConfig): TranscriptionAgency;
|
|
2613
3943
|
export function createCameraContextAgency(config?: CameraContextConfig): CameraContextAgency;
|
|
3944
|
+
export function createUserPerceptionAgency(config?: UserPerceptionConfig, runtime?: UserPerceptionRuntime): UserPerceptionAgency;
|
|
2614
3945
|
export function createCharacterAgencies(config?: {
|
|
2615
3946
|
blink?: BlinkAgencyConfig;
|
|
2616
3947
|
gaze?: GazeConfig;
|
|
3948
|
+
gazeRuntime?: EmbodyGazeRuntime;
|
|
2617
3949
|
eyeHeadTracking?: EyeHeadTrackingConfig;
|
|
2618
|
-
gesture?:
|
|
3950
|
+
gesture?: GestureOptions;
|
|
2619
3951
|
cameraContext?: CameraContextConfig;
|
|
3952
|
+
userPerception?: UserPerceptionConfig;
|
|
3953
|
+
userPerceptionRuntime?: UserPerceptionRuntime;
|
|
2620
3954
|
transcription?: TranscriptionConfig;
|
|
2621
3955
|
conversation?: ConversationAgencyConfig;
|
|
2622
3956
|
tts?: TTSConfig;
|
|
2623
3957
|
lipSync?: LipSyncConfig;
|
|
2624
3958
|
lipSyncRuntime?: LipSyncRuntime;
|
|
2625
|
-
prosodic?:
|
|
3959
|
+
prosodic?: ProsodicOptions;
|
|
2626
3960
|
animation?: AnimationAgencyConfig;
|
|
2627
3961
|
/** Compatibility injection point passed into Conversation's private effector. */
|
|
2628
3962
|
conversationProvider?: ConversationProvider;
|
|
2629
3963
|
/** Optional society wiring / priors seed (see AgencySociety). */
|
|
2630
3964
|
agencySociety?: AgencySociety;
|
|
2631
3965
|
}): CharacterAgencies;
|
|
3966
|
+
|
|
3967
|
+
// Versioned module definitions are pure JSON authoring data, not live agencies.
|
|
3968
|
+
export type ModuleType = 'aiChat' | 'frenchQuiz' | 'slideshow' | 'questionnaire';
|
|
3969
|
+
export interface ModuleVoiceOverride {
|
|
3970
|
+
engine: 'azure' | 'webSpeech';
|
|
3971
|
+
voiceName: string;
|
|
3972
|
+
rate: number;
|
|
3973
|
+
pitch: number;
|
|
3974
|
+
volume: number;
|
|
3975
|
+
}
|
|
3976
|
+
export interface ModuleCommonSettings {
|
|
3977
|
+
language?: string;
|
|
3978
|
+
instructions?: string;
|
|
3979
|
+
greeting?: string;
|
|
3980
|
+
inputMode?: 'voice' | 'text' | 'voiceAndText';
|
|
3981
|
+
interruptionMode?: 'cancel-agent' | 'ignore';
|
|
3982
|
+
/** null inherits voice from the character profile referenced by characterBinding. */
|
|
3983
|
+
voiceOverride?: ModuleVoiceOverride | null;
|
|
3984
|
+
}
|
|
3985
|
+
export interface ModuleUISettings {
|
|
3986
|
+
layout?: 'conversation' | 'stage' | 'backdrop' | 'contentFocus';
|
|
3987
|
+
panels?: Array<'agent' | 'transcript' | 'content' | 'input' | 'progress' | 'feedback'>;
|
|
3988
|
+
actions?: Array<'answer' | 'continue' | 'back' | 'skip' | 'exit' | 'discuss'>;
|
|
3989
|
+
}
|
|
3990
|
+
export interface ModuleTypeSettings {
|
|
3991
|
+
aiChat: { autoEmotion?: boolean; emotionIntensity?: number };
|
|
3992
|
+
frenchQuiz: { autoPlay?: boolean; showInstructions?: boolean };
|
|
3993
|
+
slideshow: { autoAdvance?: boolean; allowBrowse?: boolean; followPresenter?: boolean; initialSlide?: number };
|
|
3994
|
+
questionnaire: { mode?: 'quiz' | 'diagnostic' | 'unscored'; feedbackTiming?: 'immediate' | 'end' | 'none'; allowBack?: boolean; maxAttempts?: number };
|
|
3995
|
+
}
|
|
3996
|
+
export interface ModuleSettings<T extends ModuleType = ModuleType> {
|
|
3997
|
+
common?: ModuleCommonSettings;
|
|
3998
|
+
type?: ModuleTypeSettings[T];
|
|
3999
|
+
ui?: ModuleUISettings;
|
|
4000
|
+
}
|
|
4001
|
+
export interface ModuleContentReference {
|
|
4002
|
+
contentId: string;
|
|
4003
|
+
contentType: 'htmlDeck' | 'workbook' | 'questionnaire';
|
|
4004
|
+
/** Positive immutable content revision. */
|
|
4005
|
+
revision: number;
|
|
4006
|
+
}
|
|
4007
|
+
export interface ModuleCharacterBinding {
|
|
4008
|
+
characterId: string;
|
|
4009
|
+
/** Positive profile revision; profile data is not copied into the definition. */
|
|
4010
|
+
profileRevision: number;
|
|
4011
|
+
}
|
|
4012
|
+
export type ModuleDefinition<T extends ModuleType = ModuleType> = T extends ModuleType ? {
|
|
4013
|
+
schemaVersion: 1;
|
|
4014
|
+
moduleId: string;
|
|
4015
|
+
moduleType: T;
|
|
4016
|
+
/** 0 is an unsaved draft; saved definitions use positive revisions. */
|
|
4017
|
+
revision: number;
|
|
4018
|
+
name: string;
|
|
4019
|
+
description: string;
|
|
4020
|
+
characterBinding: ModuleCharacterBinding | null;
|
|
4021
|
+
contentRefs: ModuleContentReference[];
|
|
4022
|
+
settings: ModuleSettingsPatch<ModuleSettings<T>>;
|
|
4023
|
+
} : never;
|
|
4024
|
+
export type ResolvedModuleDefinition<T extends ModuleType = ModuleType> = T extends ModuleType
|
|
4025
|
+
? Omit<ModuleDefinition<T>, 'settings'> & { settings: ModuleSettings<T> } : never;
|
|
4026
|
+
export interface ModuleValidationError { path: string; code: string; message: string }
|
|
4027
|
+
export interface ModuleValidationResult { valid: boolean; errors: ModuleValidationError[] }
|
|
4028
|
+
export interface ModuleSettingDescriptor {
|
|
4029
|
+
key: string;
|
|
4030
|
+
control: 'text' | 'textarea' | 'toggle' | 'number' | 'select' | 'multiSelect' | 'editor';
|
|
4031
|
+
label: string;
|
|
4032
|
+
help: string;
|
|
4033
|
+
default: unknown;
|
|
4034
|
+
group: 'common' | 'type' | 'ui';
|
|
4035
|
+
requiredCapabilities: string[];
|
|
4036
|
+
authorVisible: boolean;
|
|
4037
|
+
/** Editor visibility hint, not an authorization rule for participant data. */
|
|
4038
|
+
participantVisible: boolean;
|
|
4039
|
+
applyTiming: 'liveUi' | 'nextRun';
|
|
4040
|
+
options?: Array<{ value: string; label: string }>;
|
|
4041
|
+
min?: number;
|
|
4042
|
+
max?: number;
|
|
4043
|
+
maxLength?: number;
|
|
4044
|
+
editorSlot?: 'voiceOverride';
|
|
4045
|
+
}
|
|
4046
|
+
export interface ModuleTypeDescriptor {
|
|
4047
|
+
moduleType: ModuleType;
|
|
4048
|
+
label: string;
|
|
4049
|
+
available: boolean;
|
|
4050
|
+
unavailableReason: string | null;
|
|
4051
|
+
fields: ModuleSettingDescriptor[];
|
|
4052
|
+
editorSlots: Array<{ key: 'contentRefs'; editorSlot: 'deck' | 'questionnaire'; label: string; applyTiming: 'nextRun' }>;
|
|
4053
|
+
}
|
|
4054
|
+
export type ModuleReset = { $reset: true };
|
|
4055
|
+
/** Reset removes layered customization by restoring the built-in type default. */
|
|
4056
|
+
export type ModuleSettingsPatch<T> = T extends readonly unknown[] ? T | ModuleReset
|
|
4057
|
+
: T extends object ? { [K in keyof T]?: ModuleSettingsPatch<T[K]> } | ModuleReset
|
|
4058
|
+
: T | ModuleReset;
|
|
4059
|
+
export interface ModuleResolutionOptions {
|
|
4060
|
+
userDefaults?: ModuleSettingsPatch<ModuleSettings>;
|
|
4061
|
+
sessionOverrides?: ModuleSettingsPatch<ModuleSettings>;
|
|
4062
|
+
}
|
|
4063
|
+
export interface ModuleLaunchOptions extends ModuleResolutionOptions { sessionId: string; launchedAt: string }
|
|
4064
|
+
export interface ModuleLaunchSnapshot {
|
|
4065
|
+
schemaVersion: 1;
|
|
4066
|
+
sessionId: string;
|
|
4067
|
+
launchedAt: string;
|
|
4068
|
+
definitionIdentity: { moduleId: string; moduleType: ModuleType; schemaVersion: 1; revision: number };
|
|
4069
|
+
definition: ResolvedModuleDefinition;
|
|
4070
|
+
}
|
|
4071
|
+
export function getModuleTypeDescriptors(): ModuleTypeDescriptor[];
|
|
4072
|
+
export function getModuleDefinitionSchema(): Record<string, unknown>;
|
|
4073
|
+
export function getModuleSettingsDefaults<T extends ModuleType>(moduleType: T): ModuleSettings<T>;
|
|
4074
|
+
export function validateModuleDefinition(definition: unknown): ModuleValidationResult;
|
|
4075
|
+
/** Throws on unknown/invalid fields or versions; never mutates supplied data. */
|
|
4076
|
+
export function resolveModuleDefinition<T extends ModuleType>(definition: ModuleDefinition<T>, options?: ModuleResolutionOptions): ResolvedModuleDefinition<T>;
|
|
4077
|
+
/** coveredKeys must enumerate both rendered editors and effective runtime consumers. */
|
|
4078
|
+
export function validateModuleCapabilityCoverage(moduleType: ModuleType, coveredKeys: string[]): ModuleValidationResult;
|
|
4079
|
+
/** Detached JSON snapshot; unavailable type registrations cannot launch. */
|
|
4080
|
+
export function createModuleLaunchSnapshot(definition: ModuleDefinition, options: ModuleLaunchOptions): ModuleLaunchSnapshot;
|
|
4081
|
+
|
|
4082
|
+
/** Immutable authored content. This first version supports unscored questions only. */
|
|
4083
|
+
export interface QuestionnaireQuestionBase {
|
|
4084
|
+
/** Stable ASCII identifier, 1–120 characters; compatible with InteractionItemRef. */
|
|
4085
|
+
questionId: string;
|
|
4086
|
+
prompt: string;
|
|
4087
|
+
required: boolean;
|
|
4088
|
+
/** Private editorial notes, excluded from participant/Conversation projections. */
|
|
4089
|
+
authorNotes?: string;
|
|
4090
|
+
}
|
|
4091
|
+
export interface QuestionnaireChoiceQuestion extends QuestionnaireQuestionBase {
|
|
4092
|
+
kind: 'singleChoice';
|
|
4093
|
+
options: Array<{ optionId: string; label: string }>;
|
|
4094
|
+
}
|
|
4095
|
+
export interface QuestionnaireTextQuestion extends QuestionnaireQuestionBase {
|
|
4096
|
+
kind: 'text';
|
|
4097
|
+
/** Unicode codepoints after ECMAScript whitespace trimming; 0–16000. */
|
|
4098
|
+
minLength: number;
|
|
4099
|
+
/** 1–16000; no smaller than minLength. Optional empty answers bypass length bounds. */
|
|
4100
|
+
maxLength: number;
|
|
4101
|
+
}
|
|
4102
|
+
export type QuestionnaireQuestion = QuestionnaireChoiceQuestion | QuestionnaireTextQuestion;
|
|
4103
|
+
export interface QuestionnaireContent {
|
|
4104
|
+
schemaVersion: 1;
|
|
4105
|
+
contentId: string;
|
|
4106
|
+
contentType: 'questionnaire';
|
|
4107
|
+
/** Positive immutable revision. Draft revision zero is unsupported here. */
|
|
4108
|
+
revision: number;
|
|
4109
|
+
mode: 'unscored';
|
|
4110
|
+
locale: string;
|
|
4111
|
+
instructions: string;
|
|
4112
|
+
order: 'authored';
|
|
4113
|
+
questions: QuestionnaireQuestion[];
|
|
4114
|
+
completionMessage: string;
|
|
4115
|
+
authorNotes?: string;
|
|
4116
|
+
}
|
|
4117
|
+
export type QuestionnaireParticipantQuestion = Omit<QuestionnaireChoiceQuestion, 'authorNotes'>
|
|
4118
|
+
| Omit<QuestionnaireTextQuestion, 'authorNotes'>;
|
|
4119
|
+
export type QuestionnaireParticipantContent = Omit<QuestionnaireContent, 'authorNotes' | 'questions'>
|
|
4120
|
+
& { questions: QuestionnaireParticipantQuestion[] };
|
|
4121
|
+
/** Validation data only; this does not commit an answer or advance a run. */
|
|
4122
|
+
export interface QuestionnaireAnswer {
|
|
4123
|
+
questionId: string;
|
|
4124
|
+
/** Stable option ID, trimmed text, or explicit null for an optional empty answer. */
|
|
4125
|
+
value: string | null;
|
|
4126
|
+
}
|
|
4127
|
+
export type QuestionnaireAnswerValidationResult =
|
|
4128
|
+
| { valid: true; errors: []; answer: QuestionnaireAnswer }
|
|
4129
|
+
| { valid: false; errors: ModuleValidationError[]; answer: null };
|
|
4130
|
+
export interface QuestionnaireEditorDescriptor {
|
|
4131
|
+
schemaVersion: 1;
|
|
4132
|
+
editorSlot: 'questionnaire';
|
|
4133
|
+
contentType: 'questionnaire';
|
|
4134
|
+
contentSchemaId: string;
|
|
4135
|
+
supportedModes: ['unscored'];
|
|
4136
|
+
questionKinds: ['singleChoice', 'text'];
|
|
4137
|
+
order: 'authored';
|
|
4138
|
+
runtimeAvailable: false;
|
|
4139
|
+
fields: Array<{
|
|
4140
|
+
/** Canonical content path; [] denotes an authored list item. */
|
|
4141
|
+
key: string;
|
|
4142
|
+
control: 'identity' | 'text' | 'textarea' | 'toggle' | 'number' | 'select' | 'questionList' | 'optionList';
|
|
4143
|
+
label: string;
|
|
4144
|
+
help: string;
|
|
4145
|
+
participantVisible: boolean;
|
|
4146
|
+
applyTiming: 'nextRun';
|
|
4147
|
+
options?: string[];
|
|
4148
|
+
}>;
|
|
4149
|
+
}
|
|
4150
|
+
/** Structural JSON Schema; duplicate IDs, nonblank text, bounds ordering and total size also need semantic validation. */
|
|
4151
|
+
export function getQuestionnaireContentSchema(): Record<string, unknown>;
|
|
4152
|
+
export function getQuestionnaireEditorDescriptor(): QuestionnaireEditorDescriptor;
|
|
4153
|
+
export function validateQuestionnaireContent(content: unknown): ModuleValidationResult;
|
|
4154
|
+
/** Validates and returns detached allowlisted content. Throws on malformed/unsupported authored data. */
|
|
4155
|
+
export function projectQuestionnaireContent(content: QuestionnaireContent): QuestionnaireParticipantContent;
|
|
4156
|
+
/** No coercion, correctness, attempt counting or state mutation. Required blanks fail; optional blanks normalize to null. */
|
|
4157
|
+
export function validateQuestionnaireAnswer(content: unknown, questionId: string, value: unknown): QuestionnaireAnswerValidationResult;
|
|
4158
|
+
/** Pass the resolved launch definition. Checks unscored mode and one exact pinned bank; does not authorize or launch it. */
|
|
4159
|
+
export function validateQuestionnaireBinding(definition: unknown, content: unknown): ModuleValidationResult;
|
|
4160
|
+
|
|
4161
|
+
/** Shared data contracts. Each feature agency owns its state and scheduling. */
|
|
4162
|
+
export interface InteractionIdentity {
|
|
4163
|
+
schemaVersion: 1;
|
|
4164
|
+
/** Fresh for every mount/account generation, 1–64 ASCII characters. Never reuse. */
|
|
4165
|
+
instanceId: string;
|
|
4166
|
+
/** Pinned run identity; an account change requires a new session as well. */
|
|
4167
|
+
sessionId: string;
|
|
4168
|
+
definition: ModuleLaunchSnapshot['definitionIdentity'];
|
|
4169
|
+
contentRefs: ModuleContentReference[];
|
|
4170
|
+
}
|
|
4171
|
+
export interface InteractionItemRef { itemId: string; revision: number }
|
|
4172
|
+
export type InteractionPhase = 'configured' | 'running' | 'paused' | 'completed' | 'ended';
|
|
4173
|
+
export type InteractionTarget = 'session' | 'active' | 'viewed';
|
|
4174
|
+
export interface InteractionState {
|
|
4175
|
+
identity: InteractionIdentity;
|
|
4176
|
+
phase: InteractionPhase;
|
|
4177
|
+
lifecycleRevision: number;
|
|
4178
|
+
active: { item: InteractionItemRef | null; revision: number };
|
|
4179
|
+
viewed: { item: InteractionItemRef | null; revision: number };
|
|
4180
|
+
}
|
|
4181
|
+
/** Confirmed feature-planner decisions, not unvalidated host navigation requests. */
|
|
4182
|
+
export type InteractionConfirmation =
|
|
4183
|
+
| { type: 'lifecycle'; phase: InteractionPhase }
|
|
4184
|
+
| { type: 'active' | 'viewed'; item: InteractionItemRef | null };
|
|
4185
|
+
export type InteractionJSON = null | boolean | number | string | InteractionJSON[] | { [key: string]: InteractionJSON };
|
|
4186
|
+
export interface InteractionCheckpoint<T extends InteractionJSON = InteractionJSON> {
|
|
4187
|
+
schemaVersion: 1;
|
|
4188
|
+
identity: InteractionIdentity;
|
|
4189
|
+
activeItem: InteractionItemRef | null;
|
|
4190
|
+
viewedItem: InteractionItemRef | null;
|
|
4191
|
+
/** Feature-owned, versioned domain data. This API does not persist it. */
|
|
4192
|
+
payload: T;
|
|
4193
|
+
}
|
|
4194
|
+
export interface InteractionCorrelation {
|
|
4195
|
+
schemaVersion: 1;
|
|
4196
|
+
identity: InteractionIdentity;
|
|
4197
|
+
lifecycleRevision: number;
|
|
4198
|
+
target: InteractionTarget;
|
|
4199
|
+
contextRevision: number;
|
|
4200
|
+
item: InteractionItemRef | null;
|
|
4201
|
+
/** Instance-qualified ID. Send this returned value to Conversation/adapters. */
|
|
4202
|
+
requestId: string;
|
|
4203
|
+
}
|
|
4204
|
+
/** IDs describe edge-adapter resources; DOM/Embody handles never enter snapshots. */
|
|
4205
|
+
export interface InteractionViewDescriptor {
|
|
4206
|
+
layout: NonNullable<ModuleUISettings['layout']>;
|
|
4207
|
+
panels: NonNullable<ModuleUISettings['panels']>;
|
|
4208
|
+
/** Visible controls; feature policy separately determines allowed intents. */
|
|
4209
|
+
actions: NonNullable<ModuleUISettings['actions']>;
|
|
4210
|
+
availableActions: NonNullable<ModuleUISettings['actions']>;
|
|
4211
|
+
contentSurfaceId: string | null;
|
|
4212
|
+
}
|
|
4213
|
+
export interface InteractionSnapshot<T extends InteractionJSON = InteractionJSON> {
|
|
4214
|
+
interaction: InteractionState;
|
|
4215
|
+
view: InteractionViewDescriptor;
|
|
4216
|
+
/** Participant-safe projection selected by the owning feature. */
|
|
4217
|
+
domain: T;
|
|
4218
|
+
}
|
|
4219
|
+
export interface InteractionCapabilities {
|
|
4220
|
+
moduleType: ModuleType;
|
|
4221
|
+
available: boolean;
|
|
4222
|
+
unavailableReason: string | null;
|
|
4223
|
+
layouts: Array<NonNullable<ModuleUISettings['layout']>>;
|
|
4224
|
+
actions: NonNullable<ModuleUISettings['actions']>;
|
|
4225
|
+
contentSurface: boolean;
|
|
4226
|
+
}
|
|
4227
|
+
/** Contract implemented by feature composition inside Polymer. No generic
|
|
4228
|
+
* mutable session manager is supplied. Peers route internally; hosts send
|
|
4229
|
+
* external intents and render snapshots. configure/mount must validate before
|
|
4230
|
+
* changing state; later configuration applies to a new pinned run. dispose is
|
|
4231
|
+
* idempotent and releases only owned work/subscriptions/edge resources. */
|
|
4232
|
+
export interface InteractionModule<TIntent extends InteractionJSON, TDomain extends InteractionJSON> {
|
|
4233
|
+
configure(definition: ResolvedModuleDefinition): void;
|
|
4234
|
+
mount(launch: ModuleLaunchSnapshot, instanceId: string): void;
|
|
4235
|
+
dispatch(intent: TIntent): void;
|
|
4236
|
+
snapshot(): InteractionSnapshot<TDomain>;
|
|
4237
|
+
events: PolymerStream<{ type: 'interaction.snapshot'; snapshot: InteractionSnapshot<TDomain> }>;
|
|
4238
|
+
capabilities(): InteractionCapabilities;
|
|
4239
|
+
dispose(): void;
|
|
4240
|
+
}
|
|
4241
|
+
/** Throws on unsupported identities/versions or non-JSON data; returns detached data. */
|
|
4242
|
+
export function createInteractionState(identity: InteractionIdentity): InteractionState;
|
|
4243
|
+
export function confirmInteractionTransition(state: InteractionState, confirmation: InteractionConfirmation): InteractionState;
|
|
4244
|
+
export function captureInteractionCheckpoint<T extends InteractionJSON>(state: InteractionState, payload: T): InteractionCheckpoint<T>;
|
|
4245
|
+
/** Caller validates/restores the feature payload. An ended instance cannot resume. */
|
|
4246
|
+
export function restoreInteractionCheckpoint(state: InteractionState, checkpoint: InteractionCheckpoint): InteractionState;
|
|
4247
|
+
/** Local key: 1–56 Conversation-compatible ASCII characters, unique per mount. */
|
|
4248
|
+
export function createInteractionCorrelation(state: InteractionState, localRequestKey: string, target: InteractionTarget): InteractionCorrelation;
|
|
4249
|
+
/** Use the feature's current pending request; pass null after retirement. Accepts
|
|
4250
|
+
* correlated admission errors as well as outcomes. Event-type policy is local. */
|
|
4251
|
+
export function matchesInteractionOutcome(state: InteractionState, pending: InteractionCorrelation | null, outcome: { requestId?: string }): boolean;
|
|
4252
|
+
|
|
4253
|
+
/** Embody owns the complete Three camera/annotation runtime and lifecycle. */
|
|
4254
|
+
export {
|
|
4255
|
+
DPthree,
|
|
4256
|
+
DPthreeCameraController,
|
|
4257
|
+
DPthree3DMarkers,
|
|
4258
|
+
DPthreeHTMLMarkers,
|
|
4259
|
+
DPthreeMarkers,
|
|
4260
|
+
CameraDOMControls,
|
|
4261
|
+
CameraController,
|
|
4262
|
+
Markers3D,
|
|
4263
|
+
MarkersHTML,
|
|
4264
|
+
Controls,
|
|
4265
|
+
RUNTIME_ANNOTATION_REGION_PREFIX,
|
|
4266
|
+
filterCameraViewRegions,
|
|
4267
|
+
isRuntimeAnnotationRegionName,
|
|
4268
|
+
resolveMarkerAnchorRegion,
|
|
4269
|
+
shouldProjectMarkerAnchorToSurface,
|
|
4270
|
+
shouldUseFaceCenterForMarkerAnchor,
|
|
4271
|
+
createMarkerVisibilityLifecycle,
|
|
4272
|
+
createMarkerLifecycleRevealOptions,
|
|
4273
|
+
DEFAULT_MARKER_AUTO_HIDE_MS,
|
|
4274
|
+
boneResolutionProfile,
|
|
4275
|
+
createRuntimeAnnotationPreviewLifecycle,
|
|
4276
|
+
buildRegionDisplayOptions,
|
|
4277
|
+
getRuntimeAnnotationSide,
|
|
4278
|
+
getRuntimeAUMorphAnchorPoint,
|
|
4279
|
+
getRuntimeAUMeshSideOffset,
|
|
4280
|
+
DEFAULT_PREVIEW_AUTO_CLEAR_MS,
|
|
4281
|
+
inferRuntimeAnnotationPreviewSide,
|
|
4282
|
+
pickContinuumAnnotationAuId,
|
|
4283
|
+
resolveAnnotationCharacterConfig,
|
|
4284
|
+
RustAnnotationCameraCore,
|
|
4285
|
+
createRustAnnotationCameraCore,
|
|
4286
|
+
getDefaultAnnotationLaterality,
|
|
4287
|
+
getSemanticHorizontalSignForSide,
|
|
4288
|
+
getSemanticHorizontalSign,
|
|
4289
|
+
resolveRegionCameraAngle,
|
|
4290
|
+
resolveRegionVisibilityCameraAngle,
|
|
4291
|
+
toWorldDirection,
|
|
4292
|
+
getWorldDirectionForCameraAngle,
|
|
4293
|
+
getModelLocalOrbitAngle,
|
|
4294
|
+
passesMarkerCameraAngleGate,
|
|
4295
|
+
resolveFaceCenter,
|
|
4296
|
+
detectAnnotationLaterality,
|
|
4297
|
+
} from '@lovelace_lol/embody/three';
|
|
4298
|
+
export type {
|
|
4299
|
+
DPthreeConfig,
|
|
4300
|
+
CharacterValidationResult,
|
|
4301
|
+
ValidationCategory,
|
|
4302
|
+
ValidationItem,
|
|
4303
|
+
AnnotationCharacterConfig,
|
|
4304
|
+
AnnotationAnchorPoint,
|
|
4305
|
+
AnnotationMarkerAnchor,
|
|
4306
|
+
AnnotationMarkerAnchorType,
|
|
4307
|
+
AnnotationFocusTarget,
|
|
4308
|
+
AnnotationAnchoredRegion,
|
|
4309
|
+
RuntimeAnnotationMetadata,
|
|
4310
|
+
RuntimeAnnotationOptions,
|
|
4311
|
+
RuntimeAnnotationRegionSummary,
|
|
4312
|
+
RuntimeAnnotationSide,
|
|
4313
|
+
RuntimeAnnotationTargetType,
|
|
4314
|
+
CameraState,
|
|
4315
|
+
FocusPosition,
|
|
4316
|
+
DPthreeCameraControllerConfig,
|
|
4317
|
+
RegionChangeCallback,
|
|
4318
|
+
CharacterChangeCallback,
|
|
4319
|
+
DPthreeRegion,
|
|
4320
|
+
DPthreeCharacterConfig,
|
|
4321
|
+
DPthreeRegistry,
|
|
4322
|
+
DPthreeRegionChangeCallback,
|
|
4323
|
+
DPthreeCharacterChangeCallback,
|
|
4324
|
+
MarkerAnchorProjectionMode,
|
|
4325
|
+
ResolvedMarkerAnchorRegion,
|
|
4326
|
+
MarkerLifecycleRevealOptions,
|
|
4327
|
+
MarkerLifecycleRevealSource,
|
|
4328
|
+
DOMControlRegion,
|
|
4329
|
+
DOMControlsConfig,
|
|
4330
|
+
MarkerStateSnapshot,
|
|
4331
|
+
RuntimeAnnotationPreviewLifecycleOptions,
|
|
4332
|
+
} from '@lovelace_lol/embody/three';
|