@ai-presence/face 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # @ai-presence/face
2
+
3
+ Reference face renderer primitives for AI Presence Kit.
4
+
5
+ This package maps canonical presence snapshots from `@ai-presence/core` to renderer-specific face controls. The expression mapper remains available, and the additive controller APIs turn the same interaction-posture snapshot into parallel micro-decisions and deterministic per-frame micro-movement for gaze, blink, brows, mouth, posture, and motion.
6
+
7
+ ```js
8
+ import { faceExpressionForPresence } from "@ai-presence/face";
9
+
10
+ const expression = faceExpressionForPresence(snapshot);
11
+ ```
12
+
13
+ ```js
14
+ import { faceControllerDecisionsForPresence, faceControlsForPresence } from "@ai-presence/face";
15
+
16
+ const controls = faceControlsForPresence(snapshot, { trace });
17
+ const report = faceControllerDecisionsForPresence(snapshot, { trace });
18
+
19
+ renderer.setGaze(controls.gaze);
20
+ renderer.setMouth(controls.mouth);
21
+
22
+ console.log(report.decisions.gaze.controller); // "gaze-controller"
23
+ ```
24
+
25
+ ```js
26
+ import {
27
+ faceControllerCoherenceForFrame,
28
+ faceControllerDecisionTraceForFrame,
29
+ faceControllerFrameForPresence,
30
+ } from "@ai-presence/face";
31
+
32
+ const frameReport = faceControllerFrameForPresence(snapshot, {
33
+ trace,
34
+ timeMs: performance.now(),
35
+ motionScale: matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : 1,
36
+ });
37
+ const decisionTrace = faceControllerDecisionTraceForFrame(frameReport);
38
+
39
+ renderer.setGaze(frameReport.frame.gaze);
40
+ renderer.setBlink(frameReport.frame.blink);
41
+ renderer.setPosture(frameReport.frame.posture);
42
+
43
+ console.log(frameReport.coherence.rendererSafe); // true
44
+ console.log(faceControllerCoherenceForFrame(frameReport).channels); // ["gaze", "blink", "brows", "mouth", "posture", "motion"]
45
+ console.log(decisionTrace.decisions.gaze.control.target); // "response-origin"
46
+ console.log(decisionTrace.transitionContext);
47
+ // { previousState: "ready", transitionEvent: "submit", transitionAgeMs: 80 }
48
+ ```
49
+
50
+ ```js
51
+ import { renderPresenceFaceSvg } from "@ai-presence/face";
52
+
53
+ const result = renderPresenceFaceSvg(snapshot, {
54
+ trace,
55
+ timeMs: performance.now(),
56
+ motionScale: 0,
57
+ });
58
+
59
+ container.innerHTML = result.svg;
60
+ console.log(result.channelEvidence.mouth.frame.shape);
61
+ console.log(result.attributes.motionScale); // "0"
62
+ console.log(result.decisionTrace.decisionCount); // 6
63
+ console.log(result.attributes.decisionTrace); // "complete"
64
+ ```
65
+
66
+ The controller does not claim hidden internal state. It stays grounded in observable states such as `reading`, `thinking`, `waiting`, `streaming`, `speaking`, `interrupted`, and `ready`, then lets each facial subsystem make a small local decision from the shared snapshot and optional trace/history.
67
+
68
+ `faceControlsForPresence` remains the renderer-friendly compatibility surface. `faceControllerDecisionsForPresence` exposes the same composition as an inspection report:
69
+
70
+ ```js
71
+ {
72
+ state: "waiting",
73
+ expression: "listening",
74
+ sharedInputs: {
75
+ state: "waiting",
76
+ attentionTarget: "response",
77
+ latencyPhase: "before-output"
78
+ },
79
+ decisions: {
80
+ gaze: { channel: "gaze", controller: "gaze-controller", reads: ["state", "attentionTarget", "transitionEvent", "..."], control: {} },
81
+ blink: { channel: "blink", controller: "blink-controller", reads: ["state", "..."], control: {} },
82
+ brows: { channel: "brows", controller: "brows-controller", reads: ["state", "transitionEvent", "transitionAgeMs", "..."], control: {} },
83
+ mouth: { channel: "mouth", controller: "mouth-controller", reads: ["state", "speechActivity", "transitionEvent", "..."], control: {} },
84
+ posture: { channel: "posture", controller: "posture-controller", reads: ["state", "energy", "transitionEvent", "..."], control: {} },
85
+ motion: { channel: "motion", controller: "motion-controller", reads: ["state", "anticipation", "..."], control: {} }
86
+ }
87
+ }
88
+ ```
89
+
90
+ `faceControllerFrameForPresence` returns the same report fields plus a frozen `frame` object and frozen `coherence` audit. The frame keeps controller decisions stable and adds bounded temporal values such as blink `phase`, mouth `beat`, posture `breath`, and motion offsets so renderers can animate interaction posture without adding their own timing policy.
91
+
92
+ `faceControllerDecisionTraceForFrame(frameReport)` turns a frame report into bounded per-channel controller evidence. It keeps all six channels inspectable as local decisions before the composed frame is consumed by a renderer:
93
+
94
+ ```js
95
+ {
96
+ channels: ["gaze", "blink", "brows", "mouth", "posture", "motion"],
97
+ transitionContext: {
98
+ previousState: "ready",
99
+ transitionEvent: "submit",
100
+ transitionAgeMs: 80
101
+ },
102
+ decisionCount: 6,
103
+ complete: true,
104
+ rendererSafe: true,
105
+ warningCount: 0,
106
+ decisions: {
107
+ gaze: {
108
+ channel: "gaze",
109
+ controller: "gaze-controller",
110
+ reads: ["state", "detail.question", "attentionTarget", "transitionEvent", "..."],
111
+ control: { target: "response-origin", x: -0.08, y: -0.04, focus: 0.66 },
112
+ frame: { target: "response-origin", x: -0.079, y: -0.044, focus: 0.66, driftX: 0.007, driftY: -0.032 },
113
+ present: true,
114
+ bounded: true,
115
+ rendererSafe: true,
116
+ warningCount: 0,
117
+ warnings: []
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ Use the decision trace for debug UIs, tests, logs, and adapter smoke output that need to show which controller read which runtime fields without parsing full internal control objects or core trace history. `transitionContext` is renderer-owned evidence that a fresh `submit`, `stream-open`, `token`, or `interrupt` cue was available to micro-controllers such as gaze, blink, brows, mouth, posture, and motion. It is evidence for observable interaction posture, not a claim about hidden user or model state.
124
+
125
+ The coherence audit proves the six independently decided channels compose into one renderer-consumable frame:
126
+
127
+ ```js
128
+ {
129
+ channels: ["gaze", "blink", "brows", "mouth", "posture", "motion"],
130
+ complete: true,
131
+ bounded: true,
132
+ rendererSafe: true,
133
+ summary: {
134
+ channelCount: 6,
135
+ presentChannelCount: 6,
136
+ boundedChannelCount: 6,
137
+ gazeTarget: "response-origin",
138
+ gazeFocus: 0.66,
139
+ blinkOpenness: 0.9,
140
+ mouthShape: "preparing",
141
+ mouthActivity: 0.16,
142
+ postureLean: 0.24,
143
+ motionEnergy: 0.46,
144
+ motionRecovery: 0
145
+ },
146
+ channelReports: {
147
+ gaze: { channel: "gaze", present: true, bounded: true, summary: {}, warnings: [] },
148
+ blink: { channel: "blink", present: true, bounded: true, summary: {}, warnings: [] },
149
+ brows: { channel: "brows", present: true, bounded: true, summary: {}, warnings: [] },
150
+ mouth: { channel: "mouth", present: true, bounded: true, summary: {}, warnings: [] },
151
+ posture: { channel: "posture", present: true, bounded: true, summary: {}, warnings: [] },
152
+ motion: { channel: "motion", present: true, bounded: true, summary: {}, warnings: [] }
153
+ },
154
+ warnings: []
155
+ }
156
+ ```
157
+
158
+ Use `faceControllerCoherenceForFrame(frameReport)` when auditing a saved or externally assembled report. Missing channels, mismatched controller metadata, invalid targets/shapes, and out-of-range numeric values make `rendererSafe` false and appear in `warnings`.
159
+
160
+ Pass `motionScale` when a downstream renderer needs reduced motion. `motionScale: 1` is the default live temporal behavior, `motionScale: 0` produces deterministic still frames across different `timeMs` values for the same snapshot/options, and values between `0` and `1` reduce temporal blink closure, drift, mouth beat, breath, anticipation/recovery kicks, motion transition offsets, and continuous motion offsets. The gaze, brows, mouth, and posture transition responses are static controller decisions from `transitionEvent` and `transitionAgeMs`; they do not read frame time, so reduced-motion frames remain deterministic while still exposing the current interaction-posture cue. The option does not remove the six controller channels or their evidence; gaze target, blink baseline, brows, mouth shape, posture, and motion decisions remain available for custom renderers.
161
+
162
+ `renderPresenceFaceSvg` is the no-DOM reference SVG surface. It calls `faceControllerFrameForPresence`, derives `faceControllerDecisionTraceForFrame` from that same frame report, returns a compact SVG string, and includes state, expression, frame data, six-channel evidence, and renderer-owned decision-trace evidence so downstream AI interfaces can inspect what drove the rendered posture without copying the browser demo internals. The SVG root mirrors the compact proof as `data-face-decision-trace*` attributes, includes `data-face-latency-phase` when shared control inputs provide it, and mirrors fresh transition evidence through `data-face-previous-state`, `data-face-transition-event`, and `data-face-transition-age-ms`.
package/dist/index.mjs ADDED
@@ -0,0 +1,21 @@
1
+ import face from "../src/presence-face.js";
2
+
3
+ export const FaceExpression = face.FaceExpression;
4
+ export const FACE_EXPRESSIONS = face.FACE_EXPRESSIONS;
5
+ export const DEFAULT_FACE_CONTROL_PROFILE = face.DEFAULT_FACE_CONTROL_PROFILE;
6
+ export const DEFAULT_FACE_MAP = face.DEFAULT_FACE_MAP;
7
+ export const FACE_CONTROL_CHANNELS = face.FACE_CONTROL_CHANNELS;
8
+ export const createFaceControllerFrameRuntime = face.createFaceControllerFrameRuntime;
9
+ export const createFaceControllerRuntime = face.createFaceControllerRuntime;
10
+ export const createFaceRenderer = face.createFaceRenderer;
11
+ export const renderPresenceFaceSvg = face.renderPresenceFaceSvg;
12
+ export const faceControllerCoherenceForFrame = face.faceControllerCoherenceForFrame;
13
+ export const faceControllerDecisionTraceForFrame = face.faceControllerDecisionTraceForFrame;
14
+ export const faceControllerFrameForPresence = face.faceControllerFrameForPresence;
15
+ export const faceControllerDecisionsForPresence = face.faceControllerDecisionsForPresence;
16
+ export const faceControlsForPresence = face.faceControlsForPresence;
17
+ export const faceExpressionForPresence = face.faceExpressionForPresence;
18
+ export const isFaceExpression = face.isFaceExpression;
19
+ export const normalizeFaceExpression = face.normalizeFaceExpression;
20
+
21
+ export default face;
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@ai-presence/face",
3
+ "version": "0.1.0",
4
+ "description": "SVG reference face renderer with parallel presence controllers.",
5
+ "type": "commonjs",
6
+ "main": "./src/presence-face.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./src/presence-face.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./src/presence-face.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./src/presence-face.js",
14
+ "default": "./src/presence-face.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src",
20
+ "README.md"
21
+ ],
22
+ "dependencies": {
23
+ "@ai-presence/core": "0.1.0"
24
+ },
25
+ "sideEffects": false,
26
+ "license": "MIT"
27
+ }
@@ -0,0 +1,346 @@
1
+ import type {
2
+ PresenceControlInputs,
3
+ PresenceLatencyPhase,
4
+ PresenceSnapshot,
5
+ PresenceStateValue,
6
+ PresenceTransitionEvent,
7
+ } from "@ai-presence/core";
8
+
9
+ export declare const FaceExpression: Readonly<{
10
+ IDLE: "idle";
11
+ LISTENING: "listening";
12
+ READING: "reading";
13
+ THINKING: "thinking";
14
+ CURIOUS: "curious";
15
+ AMUSED: "amused";
16
+ DELIGHTED: "delighted";
17
+ UNCERTAIN: "uncertain";
18
+ CONCERNED: "concerned";
19
+ READY: "ready";
20
+ SPEAKING: "speaking";
21
+ }>;
22
+
23
+ export type FaceExpressionValue = typeof FaceExpression[keyof typeof FaceExpression];
24
+
25
+ export interface FaceControlProfile {
26
+ blinkCadenceMs?: number;
27
+ drift?: number;
28
+ settleMs?: number;
29
+ }
30
+
31
+ export interface FaceControlOptions extends FaceRendererOptions {
32
+ detail?: Record<string, unknown>;
33
+ history?: ReadonlyArray<Partial<PresenceSnapshot> & Record<string, unknown>>;
34
+ /**
35
+ * Scales temporal micro-motion in generated frames and SVG output.
36
+ * Use 1 for live motion, 0 for deterministic still/reduced-motion output.
37
+ * Values outside 0..1 are clamped.
38
+ */
39
+ motionScale?: number;
40
+ now?: number | (() => number);
41
+ profile?: FaceControlProfile;
42
+ timeMs?: number | (() => number);
43
+ trace?: ReadonlyArray<Partial<PresenceSnapshot> & Record<string, unknown>> | {
44
+ getEntries(): ReadonlyArray<Partial<PresenceSnapshot> & Record<string, unknown>>;
45
+ };
46
+ }
47
+
48
+ export interface FaceGazeControl {
49
+ target: "audience" | "content" | "input" | "middle-distance" | "question" | "response-origin" | "status" | "user";
50
+ x: number;
51
+ y: number;
52
+ focus: number;
53
+ }
54
+
55
+ export interface FaceBlinkControl {
56
+ openness: number;
57
+ cadenceMs: number;
58
+ pulse: boolean;
59
+ }
60
+
61
+ export interface FaceBrowsControl {
62
+ lift: number;
63
+ pinch: number;
64
+ asymmetry: number;
65
+ }
66
+
67
+ export interface FaceMouthControl {
68
+ shape: "curious" | "downturned" | "held" | "listening" | "preparing" | "pressed" | "release" | "rest" | "soft-smile" | "speaking";
69
+ openness: number;
70
+ activity: number;
71
+ tension: number;
72
+ }
73
+
74
+ export interface FacePostureControl {
75
+ lean: number;
76
+ turn: number;
77
+ energy: number;
78
+ recovery: number;
79
+ }
80
+
81
+ export interface FaceMotionControl {
82
+ energy: number;
83
+ drift: number;
84
+ anticipation: number;
85
+ recovery: number;
86
+ settleMs: number;
87
+ }
88
+
89
+ export interface FaceGazeFrame extends FaceGazeControl {
90
+ driftX: number;
91
+ driftY: number;
92
+ }
93
+
94
+ export interface FaceBlinkFrame extends FaceBlinkControl {
95
+ phase: number;
96
+ }
97
+
98
+ export interface FaceBrowsFrame extends FaceBrowsControl {}
99
+
100
+ export interface FaceMouthFrame extends FaceMouthControl {
101
+ beat: number;
102
+ }
103
+
104
+ export interface FacePostureFrame extends FacePostureControl {
105
+ breath: number;
106
+ }
107
+
108
+ export interface FaceMotionFrame extends FaceMotionControl {
109
+ offsetX: number;
110
+ offsetY: number;
111
+ }
112
+
113
+ export interface FaceControllerFrame {
114
+ gaze: FaceGazeFrame;
115
+ blink: FaceBlinkFrame;
116
+ brows: FaceBrowsFrame;
117
+ mouth: FaceMouthFrame;
118
+ posture: FacePostureFrame;
119
+ motion: FaceMotionFrame;
120
+ }
121
+
122
+ export type FaceControlChannel = "gaze" | "blink" | "brows" | "mouth" | "posture" | "motion";
123
+
124
+ export interface FaceControllerChannelCoherence {
125
+ channel: FaceControlChannel;
126
+ present: boolean;
127
+ bounded: boolean;
128
+ summary: Readonly<Record<string, string | number | boolean | null>>;
129
+ warnings: readonly string[];
130
+ }
131
+
132
+ export interface FaceControllerCoherence {
133
+ channels: readonly FaceControlChannel[];
134
+ complete: boolean;
135
+ bounded: boolean;
136
+ rendererSafe: boolean;
137
+ summary: Readonly<{
138
+ channelCount: number;
139
+ presentChannelCount: number;
140
+ boundedChannelCount: number;
141
+ gazeTarget: FaceGazeFrame["target"] | null;
142
+ gazeFocus: number | null;
143
+ blinkOpenness: number | null;
144
+ mouthShape: FaceMouthFrame["shape"] | null;
145
+ mouthActivity: number | null;
146
+ postureLean: number | null;
147
+ motionEnergy: number | null;
148
+ motionRecovery: number | null;
149
+ }>;
150
+ channelReports: Readonly<Record<FaceControlChannel, FaceControllerChannelCoherence>>;
151
+ warnings: readonly string[];
152
+ }
153
+
154
+ export type FaceControllerDecisionTraceSummaryValue = string | number | boolean | null;
155
+
156
+ export interface FaceControllerTransitionContext {
157
+ previousState: PresenceStateValue | null;
158
+ transitionEvent: PresenceTransitionEvent | null;
159
+ transitionAgeMs: number | null;
160
+ }
161
+
162
+ export interface FaceControllerDecisionTraceChannel {
163
+ channel: FaceControlChannel;
164
+ controller: string | null;
165
+ reads: readonly string[];
166
+ control: Readonly<Record<string, FaceControllerDecisionTraceSummaryValue>>;
167
+ frame: Readonly<Record<string, FaceControllerDecisionTraceSummaryValue>>;
168
+ present: boolean;
169
+ bounded: boolean;
170
+ rendererSafe: boolean;
171
+ warningCount: number;
172
+ warnings: readonly string[];
173
+ }
174
+
175
+ export interface FaceControllerDecisionTrace {
176
+ channels: readonly FaceControlChannel[];
177
+ transitionContext: FaceControllerTransitionContext;
178
+ decisionCount: number;
179
+ complete: boolean;
180
+ rendererSafe: boolean;
181
+ warningCount: number;
182
+ warnings: readonly string[];
183
+ decisions: Readonly<Record<FaceControlChannel, FaceControllerDecisionTraceChannel>>;
184
+ }
185
+
186
+ export interface FaceControllerDecision<TControl> {
187
+ channel: FaceControlChannel;
188
+ controller: string;
189
+ reads: readonly string[];
190
+ control: TControl;
191
+ }
192
+
193
+ export interface FaceControllerDecisions {
194
+ gaze: FaceControllerDecision<FaceGazeControl>;
195
+ blink: FaceControllerDecision<FaceBlinkControl>;
196
+ brows: FaceControllerDecision<FaceBrowsControl>;
197
+ mouth: FaceControllerDecision<FaceMouthControl>;
198
+ posture: FaceControllerDecision<FacePostureControl>;
199
+ motion: FaceControllerDecision<FaceMotionControl>;
200
+ }
201
+
202
+ export interface FaceControllerDecisionReport {
203
+ state: PresenceStateValue;
204
+ expression: FaceExpressionValue;
205
+ sharedInputs: PresenceControlInputs | null;
206
+ decisions: FaceControllerDecisions;
207
+ }
208
+
209
+ export interface FaceControllerFrameReport extends FaceControllerDecisionReport {
210
+ frame: FaceControllerFrame;
211
+ coherence: FaceControllerCoherence;
212
+ }
213
+
214
+ export interface PresenceFaceSvgOptions extends FaceControlOptions {
215
+ className?: string;
216
+ height?: number;
217
+ title?: string;
218
+ width?: number;
219
+ }
220
+
221
+ export interface PresenceFaceSvgChannelEvidence<TFrame> {
222
+ controller: string;
223
+ reads: readonly string[];
224
+ frame: TFrame;
225
+ }
226
+
227
+ export interface PresenceFaceSvgChannelEvidenceMap {
228
+ gaze: PresenceFaceSvgChannelEvidence<FaceGazeFrame>;
229
+ blink: PresenceFaceSvgChannelEvidence<FaceBlinkFrame>;
230
+ brows: PresenceFaceSvgChannelEvidence<FaceBrowsFrame>;
231
+ mouth: PresenceFaceSvgChannelEvidence<FaceMouthFrame>;
232
+ posture: PresenceFaceSvgChannelEvidence<FacePostureFrame>;
233
+ motion: PresenceFaceSvgChannelEvidence<FaceMotionFrame>;
234
+ }
235
+
236
+ export interface PresenceFaceSvgAttributes {
237
+ state: PresenceStateValue;
238
+ expression: FaceExpressionValue;
239
+ channels: string;
240
+ gazeTarget: FaceGazeFrame["target"];
241
+ blinkOpenness: string;
242
+ browsPinch: string;
243
+ mouthShape: FaceMouthFrame["shape"];
244
+ postureLean: string;
245
+ motionEnergy: string;
246
+ motionScale: string;
247
+ decisionTrace: "complete" | "incomplete";
248
+ decisionTraceChannels: string;
249
+ decisionTraceDecisions: string;
250
+ decisionTraceWarnings: string;
251
+ decisionTraceRendererSafe: "true" | "false";
252
+ latencyPhase?: PresenceLatencyPhase;
253
+ previousState?: PresenceStateValue;
254
+ transitionEvent?: PresenceTransitionEvent;
255
+ transitionAgeMs?: string;
256
+ }
257
+
258
+ export interface PresenceFaceSvgRenderResult {
259
+ svg: string;
260
+ state: PresenceStateValue;
261
+ expression: FaceExpressionValue;
262
+ frame: FaceControllerFrame;
263
+ frameReport: FaceControllerFrameReport;
264
+ attributes: PresenceFaceSvgAttributes;
265
+ channelEvidence: PresenceFaceSvgChannelEvidenceMap;
266
+ decisionTrace: FaceControllerDecisionTrace;
267
+ }
268
+
269
+ export interface FaceControls {
270
+ expression: FaceExpressionValue;
271
+ gaze: FaceGazeControl;
272
+ blink: FaceBlinkControl;
273
+ brows: FaceBrowsControl;
274
+ mouth: FaceMouthControl;
275
+ posture: FacePostureControl;
276
+ motion: FaceMotionControl;
277
+ }
278
+
279
+ export interface FaceControllerRuntime {
280
+ getControls(): FaceControls | null;
281
+ update(snapshot: PresenceSnapshot | PresenceStateValue, options?: FaceControlOptions & {
282
+ update?: (controls: FaceControls, snapshot: PresenceSnapshot | PresenceStateValue) => void;
283
+ }): FaceControls;
284
+ }
285
+
286
+ export interface FaceControllerFrameRuntime {
287
+ getFrame(): FaceControllerFrameReport | null;
288
+ update(snapshot: PresenceSnapshot | PresenceStateValue, options?: FaceControlOptions & {
289
+ update?: (frame: FaceControllerFrameReport, snapshot: PresenceSnapshot | PresenceStateValue) => void;
290
+ }): FaceControllerFrameReport;
291
+ }
292
+
293
+ export interface FaceRenderer {
294
+ getExpression(): FaceExpressionValue | null;
295
+ render(snapshot: PresenceSnapshot): FaceExpressionValue;
296
+ }
297
+
298
+ export interface FaceRendererOptions {
299
+ map?: Partial<Record<PresenceStateValue, FaceExpressionValue>>;
300
+ render?: (expression: FaceExpressionValue, snapshot: PresenceSnapshot) => void;
301
+ }
302
+
303
+ export declare const FACE_EXPRESSIONS: readonly FaceExpressionValue[];
304
+ export declare const DEFAULT_FACE_CONTROL_PROFILE: Readonly<{
305
+ blinkCadenceMs: number;
306
+ drift: number;
307
+ settleMs: number;
308
+ }>;
309
+ export declare const FACE_CONTROL_CHANNELS: readonly FaceControlChannel[];
310
+ export declare const DEFAULT_FACE_MAP: Readonly<Record<PresenceStateValue, FaceExpressionValue>>;
311
+
312
+ export declare function createFaceControllerRuntime(options?: FaceControlOptions & {
313
+ update?: (controls: FaceControls, snapshot: PresenceSnapshot | PresenceStateValue) => void;
314
+ }): FaceControllerRuntime;
315
+ export declare function createFaceControllerFrameRuntime(options?: FaceControlOptions & {
316
+ update?: (frame: FaceControllerFrameReport, snapshot: PresenceSnapshot | PresenceStateValue) => void;
317
+ }): FaceControllerFrameRuntime;
318
+ export declare function createFaceRenderer(options?: FaceRendererOptions): FaceRenderer;
319
+ export declare function faceControllerDecisionsForPresence(
320
+ snapshotOrState: PresenceSnapshot | PresenceStateValue,
321
+ options?: FaceControlOptions,
322
+ ): FaceControllerDecisionReport;
323
+ export declare function faceControllerCoherenceForFrame(
324
+ frameReport?: Partial<FaceControllerFrameReport> & Record<string, unknown>,
325
+ ): FaceControllerCoherence;
326
+ export declare function faceControllerDecisionTraceForFrame(
327
+ frameReport?: Partial<FaceControllerFrameReport> & Record<string, unknown>,
328
+ ): FaceControllerDecisionTrace;
329
+ export declare function faceControllerFrameForPresence(
330
+ snapshotOrState: PresenceSnapshot | PresenceStateValue,
331
+ options?: FaceControlOptions,
332
+ ): FaceControllerFrameReport;
333
+ export declare function faceControlsForPresence(
334
+ snapshotOrState: PresenceSnapshot | PresenceStateValue,
335
+ options?: FaceControlOptions,
336
+ ): FaceControls;
337
+ export declare function faceExpressionForPresence(
338
+ snapshotOrState: PresenceSnapshot | PresenceStateValue,
339
+ options?: FaceRendererOptions & { detail?: Record<string, unknown> },
340
+ ): FaceExpressionValue;
341
+ export declare function isFaceExpression(value: unknown): value is FaceExpressionValue;
342
+ export declare function normalizeFaceExpression(value: unknown, fallback?: FaceExpressionValue): FaceExpressionValue;
343
+ export declare function renderPresenceFaceSvg(
344
+ snapshotOrState: PresenceSnapshot | PresenceStateValue,
345
+ options?: PresenceFaceSvgOptions,
346
+ ): PresenceFaceSvgRenderResult;