realtime-avatar 0.9.1 → 0.11.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 +1 -2
- package/dist/browser.d.ts +11 -1
- package/dist/browser.js +13 -1
- package/dist/{chunk-F7E4HMBW.js → chunk-MBQ2VKLC.js} +190 -79
- package/dist/{chunk-FTAD423K.js → chunk-RVBBZCVM.js} +1 -1
- package/dist/express.d.ts +2 -2
- package/dist/express.js +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +2 -2
- package/dist/index.d.ts +53 -45
- package/dist/index.js +1 -1
- package/dist/nextjs.d.ts +2 -2
- package/dist/nextjs.js +2 -2
- package/dist/{proxy-client-DlYBC6cp.d.ts → proxy-client-CWvT16wz.d.ts} +5 -20
- package/dist/react-native.d.ts +2 -2
- package/dist/react-native.js +70 -36
- package/dist/react.d.ts +19 -4
- package/dist/react.js +273 -40
- package/dist/server.d.ts +3 -2
- package/dist/server.js +1 -1
- package/dist/tanstack-start.d.ts +2 -2
- package/dist/tanstack-start.js +2 -2
- package/dist/tools.d.ts +24 -1
- package/dist/tools.js +79 -26
- package/dist/{types-QoMHpR1h.d.ts → types-DrgyCwLC.d.ts} +1 -1
- package/dist/{types-D_aIKv4P.d.ts → types-FoJMJimV.d.ts} +91 -76
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,12 +96,11 @@ rta.retimeAnchor(avatarId, anchorTimeMs) // same loop, differ
|
|
|
96
96
|
rta.deleteAvatar(avatarId)
|
|
97
97
|
|
|
98
98
|
// clip library — declared as JSON, never as URLs
|
|
99
|
-
rta.setClipLibrary(avatarId, { clips,
|
|
99
|
+
rta.setClipLibrary(avatarId, { expectedRevision, clips, idle?, on?, actions? }) // full source record + behavior; revision required
|
|
100
100
|
rta.setLoop(avatarId, { motionPrompt }) // re-direct the RESTING LOOP; clips untouched
|
|
101
101
|
rta.waitForLoop(avatarId) // block until it settles; THROWS if it failed
|
|
102
102
|
rta.waitForClips(avatarId) // block until nothing is still rendering
|
|
103
103
|
rta.listClips(avatarId) // rows + revision, anchor, eligibility
|
|
104
|
-
rta.syncClips(avatarId, clipUrls) // DEPRECATED — external-URL tier; use setClipLibrary
|
|
105
104
|
|
|
106
105
|
// assets
|
|
107
106
|
rta.createRemoteAsset({ kind, remoteUrl })
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS, P as PlayoutDelayTarget, a as applyAvatarPlayoutDelay, b as applyPlayoutDelay } from './playout-delay-DWOc8iCl.js';
|
|
2
2
|
|
|
3
|
+
type VideoSupport = {
|
|
4
|
+
supported: true;
|
|
5
|
+
} | {
|
|
6
|
+
supported: false;
|
|
7
|
+
reason: "webrtc_unavailable" | "codec_unavailable";
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
/** Check before starting a billed video session; this does not prove negotiated playback. */
|
|
11
|
+
declare function checkVideoSupport(codec?: string): VideoSupport;
|
|
12
|
+
|
|
3
13
|
/**
|
|
4
14
|
* Turning the microphone on, and saying what went wrong when it does not.
|
|
5
15
|
*
|
|
@@ -241,4 +251,4 @@ type BoomerangPlayback = {
|
|
|
241
251
|
*/
|
|
242
252
|
declare function attachBoomerangPlayback(video: HTMLVideoElement, options?: BoomerangPlaybackOptions): BoomerangPlayback;
|
|
243
253
|
|
|
244
|
-
export { type AttachRemoteAudioOptions, type AttachableTrack, type AudioCapableRoom, type BoomerangPlayback, type BoomerangPlaybackOptions, type EnableMicrophoneOptions, type MicrophoneCapableRoom, type MicrophoneFailureReason, type MicrophoneResult, type PreparableParticipant, type PreparableRoom, type PrepareAvatarRoomOptions, type PreparedAvatarRoom, type RemoteAudioAttachment, attachBoomerangPlayback, attachRemoteAudio, enableMicrophone, prepareAvatarRoom };
|
|
254
|
+
export { type AttachRemoteAudioOptions, type AttachableTrack, type AudioCapableRoom, type BoomerangPlayback, type BoomerangPlaybackOptions, type EnableMicrophoneOptions, type MicrophoneCapableRoom, type MicrophoneFailureReason, type MicrophoneResult, type PreparableParticipant, type PreparableRoom, type PrepareAvatarRoomOptions, type PreparedAvatarRoom, type RemoteAudioAttachment, type VideoSupport, attachBoomerangPlayback, attachRemoteAudio, checkVideoSupport, enableMicrophone, prepareAvatarRoom };
|
package/dist/browser.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
// ../browser/src/video-support.ts
|
|
2
|
+
function checkVideoSupport(codec = "h264") {
|
|
3
|
+
if (typeof RTCRtpReceiver === "undefined") {
|
|
4
|
+
return { supported: false, reason: "webrtc_unavailable", message: "This browser does not support realtime media." };
|
|
5
|
+
}
|
|
6
|
+
const codecs = RTCRtpReceiver.getCapabilities("video")?.codecs ?? [];
|
|
7
|
+
if (!codecs.some((entry) => entry.mimeType.toLowerCase() === `video/${codec.toLowerCase()}`)) {
|
|
8
|
+
return { supported: false, reason: "codec_unavailable", message: `This browser cannot receive ${codec.toUpperCase()} video. Use a browser with that codec before starting a video call.` };
|
|
9
|
+
}
|
|
10
|
+
return { supported: true };
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
// ../browser/src/microphone.ts
|
|
2
14
|
var HINTS = {
|
|
3
15
|
"insecure-origin": "The browser only exposes microphones on a secure origin. Serve the page over https, or open it on http://localhost \u2014 a LAN address like http://192.168.1.5 will not do.",
|
|
@@ -241,4 +253,4 @@ function now() {
|
|
|
241
253
|
return typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
242
254
|
}
|
|
243
255
|
|
|
244
|
-
export { DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS, applyAvatarPlayoutDelay, applyPlayoutDelay, attachBoomerangPlayback, attachRemoteAudio, enableMicrophone, prepareAvatarRoom };
|
|
256
|
+
export { DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS, applyAvatarPlayoutDelay, applyPlayoutDelay, attachBoomerangPlayback, attachRemoteAudio, checkVideoSupport, enableMicrophone, prepareAvatarRoom };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
// ../http-client/src/errors.ts
|
|
2
4
|
var RealtimeAvatarError = class extends Error {
|
|
3
5
|
constructor(message, options) {
|
|
@@ -21,6 +23,179 @@ var RealtimeAvatarHttpError = class extends RealtimeAvatarError {
|
|
|
21
23
|
return this.status === 402;
|
|
22
24
|
}
|
|
23
25
|
};
|
|
26
|
+
var motionIdSchema = z.string().regex(/^[A-Za-z0-9_-]{1,64}$/).refine((value) => !["__proto__", "constructor", "prototype"].includes(value), "Reserved identifier");
|
|
27
|
+
function motionRecord(valueSchema) {
|
|
28
|
+
const record = z.record(motionIdSchema, valueSchema);
|
|
29
|
+
return z.transform((value, ctx) => {
|
|
30
|
+
if (value !== null && typeof value === "object" && Object.hasOwn(value, "__proto__")) {
|
|
31
|
+
ctx.addIssue({ code: "custom", path: ["__proto__"], message: "Reserved identifier" });
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}).pipe(record);
|
|
35
|
+
}
|
|
36
|
+
var clipSourceSchema = z.union([
|
|
37
|
+
z.strictObject({ assetId: z.string().trim().min(1).max(160) }),
|
|
38
|
+
z.strictObject({
|
|
39
|
+
motionPrompt: z.string().trim().min(1).max(1200),
|
|
40
|
+
durationSeconds: z.int().min(4).max(8).optional()
|
|
41
|
+
})
|
|
42
|
+
]);
|
|
43
|
+
var clipDeclarationSchema = z.strictObject({ source: clipSourceSchema });
|
|
44
|
+
var clipListSchema = z.array(motionIdSchema).min(1).max(32).superRefine((clips, ctx) => {
|
|
45
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46
|
+
clips.forEach((clip, index) => {
|
|
47
|
+
if (seen.has(clip)) {
|
|
48
|
+
ctx.addIssue({ code: "custom", path: [index], message: `"${clip}" is already a candidate here` });
|
|
49
|
+
}
|
|
50
|
+
seen.add(clip);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
var idleSchema = z.strictObject({
|
|
54
|
+
clips: clipListSchema,
|
|
55
|
+
weight: z.number().min(0).max(100).optional()
|
|
56
|
+
});
|
|
57
|
+
var clipActionSchema = z.strictObject({
|
|
58
|
+
description: z.string().trim().min(1).max(512),
|
|
59
|
+
clips: clipListSchema
|
|
60
|
+
});
|
|
61
|
+
var clipBehaviorFields = z.strictObject({
|
|
62
|
+
idle: idleSchema.optional(),
|
|
63
|
+
/** AUTOMATIC — one reaction per speech episode, then back to idle. */
|
|
64
|
+
on: z.strictObject({
|
|
65
|
+
userSpeechStarted: z.strictObject({ clips: clipListSchema }).optional()
|
|
66
|
+
}).optional(),
|
|
67
|
+
/** REQUESTABLE, not automatic: declaring an action does not play it. */
|
|
68
|
+
actions: motionRecord(clipActionSchema).optional()
|
|
69
|
+
});
|
|
70
|
+
var clipBehaviorSchema = clipBehaviorFields;
|
|
71
|
+
function* clipReferences(behavior) {
|
|
72
|
+
if (behavior.idle) yield { clips: behavior.idle.clips, path: ["idle", "clips"] };
|
|
73
|
+
const listening = behavior.on?.userSpeechStarted;
|
|
74
|
+
if (listening) yield { clips: listening.clips, path: ["on", "userSpeechStarted", "clips"] };
|
|
75
|
+
for (const [id, action] of Object.entries(behavior.actions ?? {})) {
|
|
76
|
+
yield { clips: action.clips, path: ["actions", id, "clips"] };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var clipLibraryDeclarationSchema = z.strictObject({
|
|
80
|
+
/** CAS against the served revision: two editors cannot silently overwrite each other. */
|
|
81
|
+
expectedRevision: z.int().nonnegative(),
|
|
82
|
+
/** The complete desired media set. Anything omitted is retired. */
|
|
83
|
+
clips: motionRecord(clipDeclarationSchema).nonoptional(),
|
|
84
|
+
...clipBehaviorFields.shape
|
|
85
|
+
}).superRefine((library, ctx) => {
|
|
86
|
+
if (Object.hasOwn(library.clips, "primary")) {
|
|
87
|
+
ctx.addIssue({
|
|
88
|
+
code: "custom",
|
|
89
|
+
path: ["clips", "primary"],
|
|
90
|
+
message: "The avatar's stored source is the rest state and is not declared \u2014 pick another id"
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
for (const { clips, path } of clipReferences(library)) {
|
|
94
|
+
clips.forEach((clip, index) => {
|
|
95
|
+
if (Object.hasOwn(library.clips, clip)) return;
|
|
96
|
+
ctx.addIssue({ code: "custom", path: [...path, index], message: `Unknown clip "${clip}"` });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
z.strictObject({
|
|
101
|
+
avatar_id: z.string().min(1).max(160),
|
|
102
|
+
queue_ticket_id: z.string().min(1).max(160).optional(),
|
|
103
|
+
max_session_seconds: z.int().positive().max(180)
|
|
104
|
+
});
|
|
105
|
+
z.object({
|
|
106
|
+
avatarId: z.string(),
|
|
107
|
+
name: z.string(),
|
|
108
|
+
poster: z.string().url().nullable(),
|
|
109
|
+
idleUrl: z.string().url(),
|
|
110
|
+
revision: z.int().nonnegative(),
|
|
111
|
+
behavior: clipBehaviorSchema,
|
|
112
|
+
clips: z.array(z.strictObject({ id: motionIdSchema, url: z.url() }))
|
|
113
|
+
}).strict();
|
|
114
|
+
var schema0 = z.string();
|
|
115
|
+
var schema1 = z.enum(["queued", "generating", "ready", "failed"]);
|
|
116
|
+
var schema2 = z.url();
|
|
117
|
+
var schema3 = z.null();
|
|
118
|
+
var schema4 = z.union([schema2, schema3]);
|
|
119
|
+
var schema5 = z.enum(["generated", "uploaded"]);
|
|
120
|
+
var schema6 = z.union([schema0, schema3]);
|
|
121
|
+
var schema7 = z.int().min(-9007199254740991).max(9007199254740991);
|
|
122
|
+
var schema8 = z.union([schema7, schema3]);
|
|
123
|
+
var schema9 = z.boolean();
|
|
124
|
+
var schema10 = z.number().min(0).max(1);
|
|
125
|
+
var schema11 = z.strictObject({
|
|
126
|
+
"sameSubject": schema9,
|
|
127
|
+
"firstFrameMatchesAnchor": schema9,
|
|
128
|
+
"lastFrameMatchesAnchor": schema9,
|
|
129
|
+
"framingComparable": schema9,
|
|
130
|
+
"confidence": schema10
|
|
131
|
+
});
|
|
132
|
+
var schema12 = z.array(schema0);
|
|
133
|
+
var schema13 = z.strictObject({
|
|
134
|
+
"verdict": schema11,
|
|
135
|
+
"issues": schema12,
|
|
136
|
+
"firstFrameUrl": schema4,
|
|
137
|
+
"lastFrameUrl": schema4,
|
|
138
|
+
"trimStartMs": schema8,
|
|
139
|
+
"trimEndMs": schema8
|
|
140
|
+
});
|
|
141
|
+
var schema14 = z.union([schema13, schema3]);
|
|
142
|
+
var schema15 = z.strictObject({
|
|
143
|
+
"code": schema0,
|
|
144
|
+
"message": schema0
|
|
145
|
+
});
|
|
146
|
+
var schema16 = z.union([schema15, schema3]);
|
|
147
|
+
var schema17 = z.strictObject({
|
|
148
|
+
"clipId": schema0,
|
|
149
|
+
"status": schema1,
|
|
150
|
+
"url": schema4,
|
|
151
|
+
"source": schema5,
|
|
152
|
+
"uploadAssetId": schema6,
|
|
153
|
+
"motionPrompt": schema6,
|
|
154
|
+
"durationSeconds": schema8,
|
|
155
|
+
"anchorVersion": schema7,
|
|
156
|
+
"poseCheck": schema14,
|
|
157
|
+
"error": schema16,
|
|
158
|
+
"createdAt": schema0,
|
|
159
|
+
"updatedAt": schema0
|
|
160
|
+
});
|
|
161
|
+
var schema18 = z.array(schema17);
|
|
162
|
+
var schema19 = z.int().min(0).max(9007199254740991);
|
|
163
|
+
var schema20 = z.int().min(1).max(9007199254740991);
|
|
164
|
+
var schema21 = z.enum(["portrait", "source_frame"]);
|
|
165
|
+
var schema22 = z.strictObject({
|
|
166
|
+
"url": schema2,
|
|
167
|
+
"source": schema21,
|
|
168
|
+
"timeMs": schema8
|
|
169
|
+
});
|
|
170
|
+
var schema23 = z.union([schema22, schema3]);
|
|
171
|
+
var schema24 = z.strictObject({
|
|
172
|
+
"data": schema18,
|
|
173
|
+
"avatarId": schema0,
|
|
174
|
+
"revision": schema19,
|
|
175
|
+
"anchorVersion": schema20,
|
|
176
|
+
"anchor": schema23,
|
|
177
|
+
"clipLibraryEligible": schema9,
|
|
178
|
+
"defaultSourceAssetId": schema6,
|
|
179
|
+
"behavior": clipBehaviorSchema
|
|
180
|
+
});
|
|
181
|
+
var schema25 = z.strictObject({
|
|
182
|
+
"kept": schema12,
|
|
183
|
+
"queued": schema12,
|
|
184
|
+
"retired": schema12
|
|
185
|
+
});
|
|
186
|
+
var schema26 = z.strictObject({
|
|
187
|
+
"data": schema18,
|
|
188
|
+
"avatarId": schema0,
|
|
189
|
+
"revision": schema19,
|
|
190
|
+
"anchorVersion": schema20,
|
|
191
|
+
"anchor": schema23,
|
|
192
|
+
"clipLibraryEligible": schema9,
|
|
193
|
+
"defaultSourceAssetId": schema6,
|
|
194
|
+
"behavior": clipBehaviorSchema,
|
|
195
|
+
"plan": schema25
|
|
196
|
+
});
|
|
197
|
+
var clipLibraryResponseSchema = schema24;
|
|
198
|
+
var clipLibraryUpdateSchema = schema26;
|
|
24
199
|
|
|
25
200
|
// ../http-client/src/retry.ts
|
|
26
201
|
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 500, 502, 503, 504]);
|
|
@@ -43,7 +218,7 @@ function isTransient(cause) {
|
|
|
43
218
|
|
|
44
219
|
// ../http-client/src/client.ts
|
|
45
220
|
var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
|
|
46
|
-
var SDK_VERSION = "0.
|
|
221
|
+
var SDK_VERSION = "0.11.0";
|
|
47
222
|
var RealtimeAvatar = class {
|
|
48
223
|
#apiKey;
|
|
49
224
|
#baseUrl;
|
|
@@ -280,49 +455,20 @@ var RealtimeAvatar = class {
|
|
|
280
455
|
async deleteAvatar(avatarId) {
|
|
281
456
|
await this.#json(await this.#request("DELETE", `/avatars/${avatarId}`));
|
|
282
457
|
}
|
|
283
|
-
|
|
284
|
-
// next declare — CAS degrades to unconditional with zero signal — so it throws instead.
|
|
285
|
-
#clipEnvelope(out) {
|
|
286
|
-
if (typeof out.revision !== "number" || !Array.isArray(out.data)) {
|
|
287
|
-
throw new RealtimeAvatarError("clip library response did not match the contract");
|
|
288
|
-
}
|
|
289
|
-
return out;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Declare the avatar's full desired clip library — a declaration, not a delta. The
|
|
293
|
-
* platform reconciles it against what exists: unchanged clips are `kept` (still
|
|
294
|
-
* serving), new or changed ones are `queued` to render, and clips you dropped are
|
|
295
|
-
* `retired`. The 202 is acceptance, not readiness — poll `listClips` until no row is
|
|
296
|
-
* `queued` or `generating`. A rejected upload settles `failed`, which is terminal, so
|
|
297
|
-
* waiting for all-`ready` waits forever. While a re-render is in flight the previous
|
|
298
|
-
* take keeps serving, so a declaration never blanks a live avatar.
|
|
299
|
-
*
|
|
300
|
-
* `expectedRevision` is compare-and-set: pass the `revision` you last read and a
|
|
301
|
-
* concurrent writer surfaces as a 409 instead of a lost update. Omit it to declare
|
|
302
|
-
* unconditionally.
|
|
303
|
-
*
|
|
304
|
-
* At most 20 clips: up to eight `idle`, up to two `listen`, the rest `gesture`. Several
|
|
305
|
-
* idles are a resting ROTATION she drifts between, not alternatives to one. An uploaded
|
|
306
|
-
* clip (`source: { assetId }`) must start AND end on the avatar's rest pose — pose
|
|
307
|
-
* validation rejects it otherwise (`status: "failed"`, the verdict in `poseCheck`),
|
|
308
|
-
* and the rest of the library is untouched.
|
|
309
|
-
*/
|
|
458
|
+
/** Reconcile the complete source registry and behavior; 202 accepts work, not media readiness. */
|
|
310
459
|
async setClipLibrary(avatarId, library) {
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
)
|
|
317
|
-
);
|
|
460
|
+
const response = clipLibraryUpdateSchema.safeParse(await this.#json(
|
|
461
|
+
await this.#request("PUT", `/avatars/${avatarId}/clips`, { json: library })
|
|
462
|
+
));
|
|
463
|
+
if (!response.success) throw new RealtimeAvatarError("clip library response did not match the contract");
|
|
464
|
+
return response.data;
|
|
318
465
|
}
|
|
319
466
|
/**
|
|
320
467
|
* Re-direct the RESTING LOOP — the video she plays when nothing else is happening — from
|
|
321
468
|
* a new one-sentence description.
|
|
322
469
|
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* she rests in. This is the only thing that does.
|
|
470
|
+
* This changes the stored source — the implicit rest state — not the declared idle
|
|
471
|
+
* variations or ordinary clip assets.
|
|
326
472
|
*
|
|
327
473
|
* `202`, because the render takes minutes. Three properties, all measured against a real
|
|
328
474
|
* render rather than asserted:
|
|
@@ -406,32 +552,11 @@ var RealtimeAvatar = class {
|
|
|
406
552
|
}
|
|
407
553
|
/** The avatar's clip library: every non-retired clip, plus revision, anchor and eligibility. */
|
|
408
554
|
async listClips(avatarId) {
|
|
409
|
-
|
|
410
|
-
await this.#
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Reconcile an avatar's clip set after it changes.
|
|
417
|
-
*
|
|
418
|
-
* Required, not optional: clips are prepared once and cached by URL hash, and the serve
|
|
419
|
-
* path only LOADS that cache. A clip that has never been prepared silently does nothing on
|
|
420
|
-
* the first call after you add it. Idempotent, so calling it on every write is cheap.
|
|
421
|
-
*
|
|
422
|
-
* **At most 32 URLs per call.** This is the whole set for the avatar, not a delta, and the
|
|
423
|
-
* endpoint rejects an oversize list rather than truncating it — so a library that outgrows
|
|
424
|
-
* 32 needs the set trimmed, not split across two calls.
|
|
425
|
-
*
|
|
426
|
-
* @deprecated The externally-hosted clip tier this serves is sunsetting. Declare the
|
|
427
|
-
* library with {@link setClipLibrary} instead — the platform renders and hosts the
|
|
428
|
-
* clips, and pose-validates uploads against the avatar's rest pose.
|
|
429
|
-
*/
|
|
430
|
-
async syncClips(avatarId, clipUrls) {
|
|
431
|
-
const out = await this.#json(
|
|
432
|
-
await this.#request("POST", `/avatars/${avatarId}/clips`, { json: { clipUrls } })
|
|
433
|
-
);
|
|
434
|
-
return { queued: out.queued ?? [], ready: out.ready ?? [], retired: out.retired ?? [] };
|
|
555
|
+
const response = clipLibraryResponseSchema.safeParse(await this.#json(
|
|
556
|
+
await this.#request("GET", `/avatars/${avatarId}/clips`)
|
|
557
|
+
));
|
|
558
|
+
if (!response.success) throw new RealtimeAvatarError("clip library response did not match the contract");
|
|
559
|
+
return response.data;
|
|
435
560
|
}
|
|
436
561
|
// ── assets ───────────────────────────────────────────────────────────────
|
|
437
562
|
/** Hand us a URL and we stream it into storage. Prefer this for anything large. */
|
|
@@ -582,20 +707,6 @@ function videoToWire(video) {
|
|
|
582
707
|
}
|
|
583
708
|
out.support_edits = edits;
|
|
584
709
|
}
|
|
585
|
-
if (video.states) {
|
|
586
|
-
out.clip_library = Object.entries(video.states).map(([id, state]) => {
|
|
587
|
-
const clip = {
|
|
588
|
-
clip_id: id,
|
|
589
|
-
source_video_url: state.url,
|
|
590
|
-
trigger: "directive",
|
|
591
|
-
// `when` is the public name for this cue. The wire also still accepts the older
|
|
592
|
-
// `hint`; send one name only, and prefer the one the docs and types use.
|
|
593
|
-
when: state.when
|
|
594
|
-
};
|
|
595
|
-
if (state.weight !== void 0) clip.weight = state.weight;
|
|
596
|
-
return clip;
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
710
|
return out;
|
|
600
711
|
}
|
|
601
712
|
function toAvatar(raw) {
|
|
@@ -680,4 +791,4 @@ function isQueued(result) {
|
|
|
680
791
|
return "queued" in result;
|
|
681
792
|
}
|
|
682
793
|
|
|
683
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript };
|
|
794
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-MBQ2VKLC.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
package/dist/express.d.ts
CHANGED
package/dist/express.js
CHANGED
package/dist/hono.d.ts
CHANGED
package/dist/hono.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as
|
|
2
|
-
export {
|
|
1
|
+
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as ClipLibraryDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as AssetKind, h as Asset, i as ListSessionsOptions, U as UsageSessionPage, j as UsageSession, k as CreditBalance, T as TranscriptPayload } from './types-FoJMJimV.js';
|
|
2
|
+
export { l as AvatarClip, m as CallConnection, n as CallQueued, o as ClipDeclaration, p as ClipLibraryPlan, q as ClipSource, r as ContextMessage, s as EndCallReason, V as VideoPolicy, t as isQueued } from './types-FoJMJimV.js';
|
|
3
|
+
import { z } from 'zod';
|
|
3
4
|
|
|
4
5
|
interface RealtimeAvatarOptions {
|
|
5
6
|
/** `tic_live_…` or `tic_test_…`. Server-side only — never ship this to a browser. */
|
|
@@ -169,36 +170,14 @@ declare class RealtimeAvatar {
|
|
|
169
170
|
*/
|
|
170
171
|
retimeAnchor(avatarId: string, anchorTimeMs: number): Promise<Avatar>;
|
|
171
172
|
deleteAvatar(avatarId: string): Promise<void>;
|
|
172
|
-
/**
|
|
173
|
-
|
|
174
|
-
* platform reconciles it against what exists: unchanged clips are `kept` (still
|
|
175
|
-
* serving), new or changed ones are `queued` to render, and clips you dropped are
|
|
176
|
-
* `retired`. The 202 is acceptance, not readiness — poll `listClips` until no row is
|
|
177
|
-
* `queued` or `generating`. A rejected upload settles `failed`, which is terminal, so
|
|
178
|
-
* waiting for all-`ready` waits forever. While a re-render is in flight the previous
|
|
179
|
-
* take keeps serving, so a declaration never blanks a live avatar.
|
|
180
|
-
*
|
|
181
|
-
* `expectedRevision` is compare-and-set: pass the `revision` you last read and a
|
|
182
|
-
* concurrent writer surfaces as a 409 instead of a lost update. Omit it to declare
|
|
183
|
-
* unconditionally.
|
|
184
|
-
*
|
|
185
|
-
* At most 20 clips: up to eight `idle`, up to two `listen`, the rest `gesture`. Several
|
|
186
|
-
* idles are a resting ROTATION she drifts between, not alternatives to one. An uploaded
|
|
187
|
-
* clip (`source: { assetId }`) must start AND end on the avatar's rest pose — pose
|
|
188
|
-
* validation rejects it otherwise (`status: "failed"`, the verdict in `poseCheck`),
|
|
189
|
-
* and the rest of the library is untouched.
|
|
190
|
-
*/
|
|
191
|
-
setClipLibrary(avatarId: string, library: {
|
|
192
|
-
clips: readonly ClipDeclaration[];
|
|
193
|
-
expectedRevision?: number;
|
|
194
|
-
}): Promise<ClipLibraryUpdate>;
|
|
173
|
+
/** Reconcile the complete source registry and behavior; 202 accepts work, not media readiness. */
|
|
174
|
+
setClipLibrary(avatarId: string, library: ClipLibraryDeclaration): Promise<ClipLibraryUpdate>;
|
|
195
175
|
/**
|
|
196
176
|
* Re-direct the RESTING LOOP — the video she plays when nothing else is happening — from
|
|
197
177
|
* a new one-sentence description.
|
|
198
178
|
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* she rests in. This is the only thing that does.
|
|
179
|
+
* This changes the stored source — the implicit rest state — not the declared idle
|
|
180
|
+
* variations or ordinary clip assets.
|
|
202
181
|
*
|
|
203
182
|
* `202`, because the render takes minutes. Three properties, all measured against a real
|
|
204
183
|
* render rather than asserted:
|
|
@@ -252,22 +231,6 @@ declare class RealtimeAvatar {
|
|
|
252
231
|
}): Promise<ClipLibrary>;
|
|
253
232
|
/** The avatar's clip library: every non-retired clip, plus revision, anchor and eligibility. */
|
|
254
233
|
listClips(avatarId: string): Promise<ClipLibrary>;
|
|
255
|
-
/**
|
|
256
|
-
* Reconcile an avatar's clip set after it changes.
|
|
257
|
-
*
|
|
258
|
-
* Required, not optional: clips are prepared once and cached by URL hash, and the serve
|
|
259
|
-
* path only LOADS that cache. A clip that has never been prepared silently does nothing on
|
|
260
|
-
* the first call after you add it. Idempotent, so calling it on every write is cheap.
|
|
261
|
-
*
|
|
262
|
-
* **At most 32 URLs per call.** This is the whole set for the avatar, not a delta, and the
|
|
263
|
-
* endpoint rejects an oversize list rather than truncating it — so a library that outgrows
|
|
264
|
-
* 32 needs the set trimmed, not split across two calls.
|
|
265
|
-
*
|
|
266
|
-
* @deprecated The externally-hosted clip tier this serves is sunsetting. Declare the
|
|
267
|
-
* library with {@link setClipLibrary} instead — the platform renders and hosts the
|
|
268
|
-
* clips, and pose-validates uploads against the avatar's rest pose.
|
|
269
|
-
*/
|
|
270
|
-
syncClips(avatarId: string, clipUrls: readonly string[]): Promise<ClipSyncResult>;
|
|
271
234
|
/** Hand us a URL and we stream it into storage. Prefer this for anything large. */
|
|
272
235
|
createRemoteAsset(input: {
|
|
273
236
|
kind: AssetKind;
|
|
@@ -365,4 +328,49 @@ declare function verifyTranscript(rawBody: Uint8Array | string, headers: Headers
|
|
|
365
328
|
toleranceSeconds?: number;
|
|
366
329
|
}): Promise<TranscriptPayload>;
|
|
367
330
|
|
|
368
|
-
|
|
331
|
+
declare const clipLibraryDeclarationSchema: z.ZodObject<{
|
|
332
|
+
idle: z.ZodOptional<z.ZodObject<{
|
|
333
|
+
clips: z.ZodArray<z.ZodString>;
|
|
334
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
335
|
+
}, z.core.$strict>>;
|
|
336
|
+
on: z.ZodOptional<z.ZodObject<{
|
|
337
|
+
userSpeechStarted: z.ZodOptional<z.ZodObject<{
|
|
338
|
+
clips: z.ZodArray<z.ZodString>;
|
|
339
|
+
}, z.core.$strict>>;
|
|
340
|
+
}, z.core.$strict>>;
|
|
341
|
+
actions: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, {
|
|
342
|
+
description: string;
|
|
343
|
+
clips: string[];
|
|
344
|
+
}>, Record<string, {
|
|
345
|
+
description: string;
|
|
346
|
+
clips: string[];
|
|
347
|
+
}>>, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
348
|
+
description: z.ZodString;
|
|
349
|
+
clips: z.ZodArray<z.ZodString>;
|
|
350
|
+
}, z.core.$strict>>>>;
|
|
351
|
+
expectedRevision: z.ZodInt;
|
|
352
|
+
clips: z.ZodNonOptional<z.ZodPipe<z.ZodTransform<Record<string, {
|
|
353
|
+
source: {
|
|
354
|
+
assetId: string;
|
|
355
|
+
} | {
|
|
356
|
+
motionPrompt: string;
|
|
357
|
+
durationSeconds?: number | undefined;
|
|
358
|
+
};
|
|
359
|
+
}>, Record<string, {
|
|
360
|
+
source: {
|
|
361
|
+
assetId: string;
|
|
362
|
+
} | {
|
|
363
|
+
motionPrompt: string;
|
|
364
|
+
durationSeconds?: number | undefined;
|
|
365
|
+
};
|
|
366
|
+
}>>, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
367
|
+
source: z.ZodUnion<readonly [z.ZodObject<{
|
|
368
|
+
assetId: z.ZodString;
|
|
369
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
370
|
+
motionPrompt: z.ZodString;
|
|
371
|
+
durationSeconds: z.ZodOptional<z.ZodInt>;
|
|
372
|
+
}, z.core.$strict>]>;
|
|
373
|
+
}, z.core.$strict>>>>;
|
|
374
|
+
}, z.core.$strict>;
|
|
375
|
+
|
|
376
|
+
export { Asset, AssetKind, Avatar, AvatarSourceSwap, AvatarUpdate, CallMode, CallPolicy, ClipLibrary, ClipLibraryDeclaration, ClipLibraryUpdate, CreditBalance, EndCallOptions, ListSessionsOptions, LoopRedirect, RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, type RealtimeAvatarOptions, type StartCallOptions, StartCallResult, TranscriptPayload, UsageSession, UsageSessionPage, clipLibraryDeclarationSchema, verifyTranscript };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, isQueued, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-MBQ2VKLC.js';
|
package/dist/nextjs.d.ts
CHANGED
package/dist/nextjs.js
CHANGED
|
@@ -101,11 +101,6 @@ declare const sessionClipSchema: z.ZodObject<{
|
|
|
101
101
|
type SessionClip = z.infer<typeof sessionClipSchema>;
|
|
102
102
|
declare const sessionBehaviorSchema: z.ZodObject<{
|
|
103
103
|
gestures_enabled: z.ZodOptional<z.ZodBoolean>;
|
|
104
|
-
gesture_freq: z.ZodOptional<z.ZodEnum<{
|
|
105
|
-
sparse: "sparse";
|
|
106
|
-
balanced: "balanced";
|
|
107
|
-
lively: "lively";
|
|
108
|
-
}>>;
|
|
109
104
|
}, z.core.$strict>;
|
|
110
105
|
type SessionBehavior = z.infer<typeof sessionBehaviorSchema>;
|
|
111
106
|
/**
|
|
@@ -206,11 +201,6 @@ declare const liveKitSessionRequestSchema: z.ZodObject<{
|
|
|
206
201
|
}, z.core.$strict>>>;
|
|
207
202
|
behavior: z.ZodOptional<z.ZodObject<{
|
|
208
203
|
gestures_enabled: z.ZodOptional<z.ZodBoolean>;
|
|
209
|
-
gesture_freq: z.ZodOptional<z.ZodEnum<{
|
|
210
|
-
sparse: "sparse";
|
|
211
|
-
balanced: "balanced";
|
|
212
|
-
lively: "lively";
|
|
213
|
-
}>>;
|
|
214
204
|
}, z.core.$strict>>;
|
|
215
205
|
renderBackend: z.ZodOptional<z.ZodString>;
|
|
216
206
|
supportEdits: z.ZodOptional<z.ZodObject<{
|
|
@@ -407,6 +397,8 @@ type AvatarVideoSurfaceProps = {
|
|
|
407
397
|
* avatars with no idle clip; the poster floor then shows at rest.
|
|
408
398
|
*/
|
|
409
399
|
idleVideoUrl: string | null;
|
|
400
|
+
/** Reports presented-layer changes, not the agent's requested speaking state. */
|
|
401
|
+
onLiveVisibilityChange?: (visible: boolean) => void;
|
|
410
402
|
/**
|
|
411
403
|
* The avatar's PORTRAIT (its face) — the DEEPEST floor, rendered behind the idle
|
|
412
404
|
* clip and the live video whenever provided. It paints IMMEDIATELY on connect
|
|
@@ -1442,7 +1434,7 @@ type UseRealtimeSessionInput<T extends LLMProvider = LLMProvider> = UseSessionLi
|
|
|
1442
1434
|
onEnded?: (e: EndedEvent) => void;
|
|
1443
1435
|
/** The avatar's behavior changed (listening/thinking/idle/special clips). */
|
|
1444
1436
|
onBehaviorChange?: (b: BehaviorSnapshot) => void;
|
|
1445
|
-
/** A clip request was answered (also resolved on the
|
|
1437
|
+
/** A clip request was answered (also resolved on the performAction promise). */
|
|
1446
1438
|
onClipResult?: (r: ClipResult) => void;
|
|
1447
1439
|
};
|
|
1448
1440
|
/**
|
|
@@ -1495,15 +1487,8 @@ type RealtimeSessionApi = SessionLifecycleApi & {
|
|
|
1495
1487
|
end: (reason?: EndReason) => void;
|
|
1496
1488
|
/** The avatar's live nonverbal behavior, or null pre-choreo (see {@link BehaviorSnapshot}). */
|
|
1497
1489
|
behavior: BehaviorSnapshot | null;
|
|
1498
|
-
/**
|
|
1499
|
-
|
|
1500
|
-
* gift moment); a `special`-role clip pins for `holdSeconds` (3-20, default 8).
|
|
1501
|
-
* Scheduled at the next seamless swap point, never a hard cut. Resolves with the
|
|
1502
|
-
* worker's verdict (`accepted:false` + reason on refusal / not connected /
|
|
1503
|
-
* timeout) — never rejects, so the app can always fall back to text-only behavior.
|
|
1504
|
-
*/
|
|
1505
|
-
performClip: (clipId: string, opts?: {
|
|
1506
|
-
holdSeconds?: number;
|
|
1490
|
+
/** Request a declared semantic action; acceptance schedules it and does not prove playback. */
|
|
1491
|
+
performAction: (actionId: string, opts?: {
|
|
1507
1492
|
timeoutMs?: number;
|
|
1508
1493
|
}) => Promise<ClipResult>;
|
|
1509
1494
|
/** Inbound `rta.lifecycle` frames (the bridge decodes RoomEvent.DataReceived). */
|
package/dist/react-native.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LiveKitRoomProps } from '@livekit/react-native';
|
|
2
2
|
export { AudioSession, VideoTrack, VideoTrackProps, registerGlobals } from '@livekit/react-native';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
|
-
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-
|
|
5
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-CWvT16wz.js';
|
|
5
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, h as CallTranscriptSegment, i as CartesiaTtsModel, j as ClipResult, k as ClosingTurnResult, l as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, m as DEFAULT_CREDITS_LOW_LEAD_SECONDS, n as DEFAULT_GOVERNOR_CONFIG, o as DEFAULT_GRACE_CEILING_SECONDS, p as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, q as DEFAULT_IDLE_SECONDS, r as DEFAULT_IDLE_WARN_LEAD_SECONDS, s as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, t as EndedEvent, u as ExtendResult, F as FishTtsModel, v as FreezeReadingFn, G as Governor, w as GovernorAction, x as GovernorConfig, y as GovernorSignal, z as GovernorState, H as GraceWindowClosedEvent, I as GraceWindowOpenEvent, J as GraceWindowState, K as IdleWarningEvent, M as InboundRtpCursor, N as InboundRtpReading, O as KnownBehaviorState, P as LLMProvider, Q as LLMSelection, R as LiveKitAvatarGrantState, S as LiveKitAvatarGrantStatus, T as LiveKitCapacityState, U as LiveKitConnectionStatus, V as LiveKitSessionRequest, W as LiveKitSessionStartResult, X as MAX_RECONNECT_ATTEMPTS, Y as MAX_SESSION_INSTRUCTIONS_CHARS, Z as ProxyClientOptions, _ as QualityCap, $ as RECONNECT_BACKOFF_MS, a0 as RealtimeAvatarRequestOptions, a1 as RealtimeSessionApi, a2 as RealtimeSessionMedia, a3 as RealtimeSessionRoomSinks, a4 as ReconnectPolicy, a5 as ReconnectingEvent, a6 as RecoveryState, a7 as RetryStep, a8 as SessionBehavior, a9 as SessionClip, aa as SessionClocks, ab as SessionEndReason, ac as SessionLifecycleApi, ad as SessionLifecyclePhase, ae as SessionLifecyclePhaseKind, af as SessionLifecycleRoomBridge, ag as SessionLifecycleRoomBridgeProps, ah as SurfaceLayers, ai as TurnState, aj as TurnTimeoutEvent, ak as UseAvatarQualityGovernorInput, al as UseLiveKitAvatarGrantInput, am as UseRealtimeSessionInput, an as UseSessionLifecycleInput, ao as VoiceSpec, ap as VoiceSpecInput, aq as capacityErrorFromBusy, ar as capacityStateFromGrant, as as createProxyClient, at as isNativeLiveTrackSubscribed, au as knownBehaviorStates, av as mapTurnState, aw as readInboundRtp, ax as sessionBehaviorSchema, ay as sessionClipSchema, az as splitCallTranscript, aA as useAvatarAdaptivePlayoutDelay, aB as useAvatarPlayoutDelay, aC as useAvatarQualityGovernor, aD as useCallTranscript, aE as useLiveKitAvatarGrant, aF as useLiveTrackProducing, aG as useMicLease, aH as useRealtimeSession, aI as useReleaseMicLeaseOnTrackEnded, aJ as useSessionLifecycle } from './proxy-client-CWvT16wz.js';
|
|
6
6
|
import { StyleProp, ViewStyle } from 'react-native';
|
|
7
7
|
export { useChat, useConnectionState, useLocalParticipant, useRoomContext, useTrackToggle, useTranscriptions, useVoiceAssistant } from '@livekit/components-react';
|
|
8
8
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|