realtime-avatar 0.16.0 → 0.17.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 +21 -2
- package/dist/{chunk-2TNFET3Q.js → chunk-27BB4DQ2.js} +1 -1
- package/dist/chunk-MCIXU6XP.js +33 -0
- package/dist/{chunk-V26PE2M3.js → chunk-OESXLLQB.js} +16 -4
- package/dist/connection-history-CXL5QE56.js +1 -0
- package/dist/connection-history.d.ts +121 -0
- package/dist/connection-history.js +1 -0
- package/dist/express.d.ts +2 -2
- package/dist/express.js +3 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +3 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +2 -1
- package/dist/nextjs.d.ts +2 -2
- package/dist/nextjs.js +3 -2
- package/dist/{proxy-client-Bu-5QFhA.d.ts → proxy-client-DmJVj18Z.d.ts} +7 -1
- package/dist/react-native.d.ts +2 -2
- package/dist/react-native.js +150 -6
- package/dist/react.d.ts +2 -2
- package/dist/react.js +150 -6
- package/dist/server.d.ts +2 -1
- package/dist/server.js +2 -1
- package/dist/tanstack-start.d.ts +2 -2
- package/dist/tanstack-start.js +3 -2
- package/dist/{types-VOv0vsFs.d.ts → types-BnlnrYgN.d.ts} +24 -0
- package/dist/{types-Bphj69NC.d.ts → types-CFkiNV3f.d.ts} +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A live character your users can talk to — voice, or voice and video. She liste
|
|
|
4
4
|
speaks, so you can interrupt her mid-sentence and she stops, the way a person stops.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
|
-
npm install --save-exact realtime-avatar@0.
|
|
7
|
+
npm install --save-exact realtime-avatar@0.17.0
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
```ts
|
|
@@ -57,6 +57,24 @@ default); each URL expires at `expiresAt` (up to one hour, capped by retention).
|
|
|
57
57
|
access before replaying or seeking after expiry. An expired URL does not delete the file.
|
|
58
58
|
Treat the URL as private: anyone who has it can play that file until it expires.
|
|
59
59
|
|
|
60
|
+
## Optional connection history
|
|
61
|
+
|
|
62
|
+
Set `connectionHistory: true` in the server's `startCall` policy when the caller needs a
|
|
63
|
+
tenant-scoped LiveKit quality timeline. The SDK enables its collector only when RTA grants the
|
|
64
|
+
single-session capability. It receives the bridge's existing LiveKit connection snapshots,
|
|
65
|
+
deduplicates changes, batches at most 32 observations, and stops at 240; it does not poll WebRTC
|
|
66
|
+
statistics or own reconnect logic. Upload failures are bounded and never interrupt a call.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const call = await rta.startCall({ avatarId, connectionHistory: true });
|
|
70
|
+
// Relay call.raw unchanged. The browser SDK uploads capability-gated observations automatically.
|
|
71
|
+
const history = await rta.getConnectionHistory(call.sessionId);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
History is an observation of native connection state and publisher quality. It is not a recording,
|
|
75
|
+
packet-loss report, or proof that a device rendered or played a track. The read requires
|
|
76
|
+
`usage:read`; store the session ID and fetch history from your authorized backend.
|
|
77
|
+
|
|
60
78
|
Transcript delivery remains the signed `transcript` webhook configured on `startCall`. Join the
|
|
61
79
|
transcript and recordings by `sessionId`; keep your own script revision with that call. Transcript
|
|
62
80
|
timestamps describe conversation turns and do not by themselves establish frame-accurate media
|
|
@@ -137,13 +155,14 @@ all), and the `video` policy types are deliberately not one-to-one with the wire
|
|
|
137
155
|
|
|
138
156
|
```ts
|
|
139
157
|
// calls
|
|
140
|
-
rta.startCall({ avatarId, mode?, instructions?, context?, maxSeconds?, video?, recording?, transcript?, metadata? })
|
|
158
|
+
rta.startCall({ avatarId, mode?, instructions?, context?, maxSeconds?, video?, recording?, connectionHistory?, transcript?, metadata? })
|
|
141
159
|
rta.endCall(sessionId, { reason? }) // free an abandoned call's slot; idempotent, never throws
|
|
142
160
|
|
|
143
161
|
// optional recordings; server only, requires recordings:read
|
|
144
162
|
rta.listRecordings({ sessionId, limit?, cursor? })
|
|
145
163
|
rta.getRecording(recordingId)
|
|
146
164
|
rta.getRecordingAccess(recordingId)
|
|
165
|
+
rta.getConnectionHistory(sessionId) // bounded LiveKit observations; requires usage:read
|
|
147
166
|
|
|
148
167
|
// avatars
|
|
149
168
|
rta.createAvatarFromImage({ displayName, imageUrl, motionPrompt?, voice? }) // the only lane
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-OESXLLQB.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// ../http-client/src/generated/connection-history.ts
|
|
4
|
+
var ConnectionQuality = { Excellent: "excellent", Good: "good", Poor: "poor", Lost: "lost", Unknown: "unknown" };
|
|
5
|
+
var ConnectionState = { Disconnected: "disconnected", Connecting: "connecting", Connected: "connected", Reconnecting: "reconnecting", SignalReconnecting: "signalReconnecting" };
|
|
6
|
+
var MAX_CONNECTION_HISTORY_OBSERVATIONS = 240;
|
|
7
|
+
var MAX_CONNECTION_HISTORY_BATCH = 32;
|
|
8
|
+
var CONNECTION_HISTORY_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
9
|
+
var quality = z.enum(ConnectionQuality);
|
|
10
|
+
var connectionHistoryObservationSchema = z.object({
|
|
11
|
+
sequence: z.number().int().min(1).max(MAX_CONNECTION_HISTORY_OBSERVATIONS),
|
|
12
|
+
elapsedMs: z.number().int().min(0).max(864e5),
|
|
13
|
+
clientObservedAt: z.string().datetime({ offset: true }).nullable(),
|
|
14
|
+
connectionState: z.enum(ConnectionState),
|
|
15
|
+
localQuality: quality,
|
|
16
|
+
audioQuality: quality.nullable(),
|
|
17
|
+
videoQuality: quality.nullable()
|
|
18
|
+
}).strict();
|
|
19
|
+
var connectionHistoryGrantSchema = z.object({
|
|
20
|
+
endpoint: z.string().url().startsWith("https://"),
|
|
21
|
+
token: z.string().min(32).max(4096),
|
|
22
|
+
expiresAt: z.string().datetime({ offset: true })
|
|
23
|
+
}).strict();
|
|
24
|
+
var connectionHistoryUploadSchema = z.object({
|
|
25
|
+
sessionId: z.string().min(1).max(200),
|
|
26
|
+
observations: z.array(connectionHistoryObservationSchema).min(1).max(MAX_CONNECTION_HISTORY_BATCH)
|
|
27
|
+
}).strict();
|
|
28
|
+
var connectionHistoryResponseSchema = z.object({
|
|
29
|
+
sessionId: z.string().min(1).max(200),
|
|
30
|
+
observations: z.array(connectionHistoryObservationSchema).max(MAX_CONNECTION_HISTORY_OBSERVATIONS)
|
|
31
|
+
}).strict();
|
|
32
|
+
|
|
33
|
+
export { CONNECTION_HISTORY_RETENTION_MS, MAX_CONNECTION_HISTORY_BATCH, MAX_CONNECTION_HISTORY_OBSERVATIONS, connectionHistoryGrantSchema, connectionHistoryObservationSchema, connectionHistoryResponseSchema, connectionHistoryUploadSchema };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { connectionHistoryGrantSchema } from './chunk-MCIXU6XP.js';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
// ../http-client/src/errors.ts
|
|
@@ -432,7 +433,8 @@ z.object({
|
|
|
432
433
|
render_backend: renderBackendSchema.optional(),
|
|
433
434
|
support_edits: sessionSupportEditsSchema.optional(),
|
|
434
435
|
transcript_webhook: transcriptWebhookSchema.optional(),
|
|
435
|
-
client_metadata: clientMetadataSchema.optional()
|
|
436
|
+
client_metadata: clientMetadataSchema.optional(),
|
|
437
|
+
connection_history: z.boolean().optional()
|
|
436
438
|
}).strict().superRefine((value, ctx) => {
|
|
437
439
|
if (value.support_edits && value.render_backend === "generative") {
|
|
438
440
|
ctx.addIssue({
|
|
@@ -497,10 +499,12 @@ z.object({
|
|
|
497
499
|
renderBackend: renderBackendSchema.optional(),
|
|
498
500
|
supportEdits: sessionSupportEditsSchema.optional(),
|
|
499
501
|
transcriptWebhook: transcriptWebhookSchema.optional(),
|
|
500
|
-
clientMetadata: clientMetadataSchema.optional()
|
|
502
|
+
clientMetadata: clientMetadataSchema.optional(),
|
|
503
|
+
connectionHistory: z.boolean().optional()
|
|
501
504
|
}).strict();
|
|
502
505
|
var liveKitSessionGrantSchema = z.object({
|
|
503
506
|
recording: recordingArtifactSchema.optional(),
|
|
507
|
+
connection_history: connectionHistoryGrantSchema.optional(),
|
|
504
508
|
status: z.literal("ready").default("ready"),
|
|
505
509
|
session_id: z.string().min(1),
|
|
506
510
|
room_name: z.string().min(1),
|
|
@@ -596,7 +600,7 @@ z.enum([
|
|
|
596
600
|
|
|
597
601
|
// ../http-client/src/client.ts
|
|
598
602
|
var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
|
|
599
|
-
var SDK_VERSION = "0.
|
|
603
|
+
var SDK_VERSION = "0.17.0";
|
|
600
604
|
var RealtimeAvatar = class {
|
|
601
605
|
#apiKey;
|
|
602
606
|
#baseUrl;
|
|
@@ -642,6 +646,7 @@ var RealtimeAvatar = class {
|
|
|
642
646
|
if (options.voice !== void 0) body.voice = options.voice;
|
|
643
647
|
if (options.metadata !== void 0) body.client_metadata = options.metadata;
|
|
644
648
|
if (options.recording !== void 0) body.recording = recordingModeSchema.parse(options.recording);
|
|
649
|
+
if (options.connectionHistory !== void 0) body.connection_history = options.connectionHistory;
|
|
645
650
|
if (options.clientTools) body.capabilities = ["client_tools"];
|
|
646
651
|
if (options.transcript !== void 0) {
|
|
647
652
|
body.transcript_webhook = { url: options.transcript.url, secret: options.transcript.secret };
|
|
@@ -675,7 +680,8 @@ var RealtimeAvatar = class {
|
|
|
675
680
|
idleTimeoutSeconds: grant.idle_timeout_seconds,
|
|
676
681
|
reservationExpiresAt: grant.reservation_expires_at,
|
|
677
682
|
// The parsed fields above are for YOUR logic. Relay `raw` to the client untouched:
|
|
678
|
-
// the browser SDK
|
|
683
|
+
// the browser SDK accepts provider-issued capability fields through its passthrough
|
|
684
|
+
// grant schema; forwarding verbatim preserves capabilities this wrapper does not model.
|
|
679
685
|
raw
|
|
680
686
|
};
|
|
681
687
|
}
|
|
@@ -1014,6 +1020,12 @@ var RealtimeAvatar = class {
|
|
|
1014
1020
|
async getRecordingAccess(recordingId) {
|
|
1015
1021
|
return recordingAccessResponseSchema.parse(await this.#json(await this.#request("GET", `/recordings/${encodeURIComponent(recordingId)}/access`)));
|
|
1016
1022
|
}
|
|
1023
|
+
/** Read one session's bounded LiveKit connection history. Requires `usage:read`. */
|
|
1024
|
+
async getConnectionHistory(sessionId) {
|
|
1025
|
+
if (!sessionId) throw new RealtimeAvatarError("sessionId is required");
|
|
1026
|
+
const { connectionHistoryResponseSchema } = await import('./connection-history-CXL5QE56.js');
|
|
1027
|
+
return connectionHistoryResponseSchema.parse(await this.#json(await this.#request("GET", `/sessions/${encodeURIComponent(sessionId)}/connection-history`)));
|
|
1028
|
+
}
|
|
1017
1029
|
async creditBalance() {
|
|
1018
1030
|
return await this.#json(await this.#request("GET", "/credits/balance"));
|
|
1019
1031
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CONNECTION_HISTORY_RETENTION_MS, MAX_CONNECTION_HISTORY_BATCH, MAX_CONNECTION_HISTORY_OBSERVATIONS, connectionHistoryGrantSchema, connectionHistoryObservationSchema, connectionHistoryResponseSchema, connectionHistoryUploadSchema } from './chunk-MCIXU6XP.js';
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const MAX_CONNECTION_HISTORY_OBSERVATIONS = 240;
|
|
4
|
+
declare const MAX_CONNECTION_HISTORY_BATCH = 32;
|
|
5
|
+
declare const CONNECTION_HISTORY_RETENTION_MS: number;
|
|
6
|
+
declare const connectionHistoryObservationSchema: z.ZodObject<{
|
|
7
|
+
sequence: z.ZodNumber;
|
|
8
|
+
elapsedMs: z.ZodNumber;
|
|
9
|
+
clientObservedAt: z.ZodNullable<z.ZodString>;
|
|
10
|
+
connectionState: z.ZodEnum<{
|
|
11
|
+
readonly Disconnected: "disconnected";
|
|
12
|
+
readonly Connecting: "connecting";
|
|
13
|
+
readonly Connected: "connected";
|
|
14
|
+
readonly Reconnecting: "reconnecting";
|
|
15
|
+
readonly SignalReconnecting: "signalReconnecting";
|
|
16
|
+
}>;
|
|
17
|
+
localQuality: z.ZodEnum<{
|
|
18
|
+
readonly Excellent: "excellent";
|
|
19
|
+
readonly Good: "good";
|
|
20
|
+
readonly Poor: "poor";
|
|
21
|
+
readonly Lost: "lost";
|
|
22
|
+
readonly Unknown: "unknown";
|
|
23
|
+
}>;
|
|
24
|
+
audioQuality: z.ZodNullable<z.ZodEnum<{
|
|
25
|
+
readonly Excellent: "excellent";
|
|
26
|
+
readonly Good: "good";
|
|
27
|
+
readonly Poor: "poor";
|
|
28
|
+
readonly Lost: "lost";
|
|
29
|
+
readonly Unknown: "unknown";
|
|
30
|
+
}>>;
|
|
31
|
+
videoQuality: z.ZodNullable<z.ZodEnum<{
|
|
32
|
+
readonly Excellent: "excellent";
|
|
33
|
+
readonly Good: "good";
|
|
34
|
+
readonly Poor: "poor";
|
|
35
|
+
readonly Lost: "lost";
|
|
36
|
+
readonly Unknown: "unknown";
|
|
37
|
+
}>>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
declare const connectionHistoryGrantSchema: z.ZodObject<{
|
|
40
|
+
endpoint: z.ZodString;
|
|
41
|
+
token: z.ZodString;
|
|
42
|
+
expiresAt: z.ZodString;
|
|
43
|
+
}, z.core.$strict>;
|
|
44
|
+
declare const connectionHistoryUploadSchema: z.ZodObject<{
|
|
45
|
+
sessionId: z.ZodString;
|
|
46
|
+
observations: z.ZodArray<z.ZodObject<{
|
|
47
|
+
sequence: z.ZodNumber;
|
|
48
|
+
elapsedMs: z.ZodNumber;
|
|
49
|
+
clientObservedAt: z.ZodNullable<z.ZodString>;
|
|
50
|
+
connectionState: z.ZodEnum<{
|
|
51
|
+
readonly Disconnected: "disconnected";
|
|
52
|
+
readonly Connecting: "connecting";
|
|
53
|
+
readonly Connected: "connected";
|
|
54
|
+
readonly Reconnecting: "reconnecting";
|
|
55
|
+
readonly SignalReconnecting: "signalReconnecting";
|
|
56
|
+
}>;
|
|
57
|
+
localQuality: z.ZodEnum<{
|
|
58
|
+
readonly Excellent: "excellent";
|
|
59
|
+
readonly Good: "good";
|
|
60
|
+
readonly Poor: "poor";
|
|
61
|
+
readonly Lost: "lost";
|
|
62
|
+
readonly Unknown: "unknown";
|
|
63
|
+
}>;
|
|
64
|
+
audioQuality: z.ZodNullable<z.ZodEnum<{
|
|
65
|
+
readonly Excellent: "excellent";
|
|
66
|
+
readonly Good: "good";
|
|
67
|
+
readonly Poor: "poor";
|
|
68
|
+
readonly Lost: "lost";
|
|
69
|
+
readonly Unknown: "unknown";
|
|
70
|
+
}>>;
|
|
71
|
+
videoQuality: z.ZodNullable<z.ZodEnum<{
|
|
72
|
+
readonly Excellent: "excellent";
|
|
73
|
+
readonly Good: "good";
|
|
74
|
+
readonly Poor: "poor";
|
|
75
|
+
readonly Lost: "lost";
|
|
76
|
+
readonly Unknown: "unknown";
|
|
77
|
+
}>>;
|
|
78
|
+
}, z.core.$strict>>;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
declare const connectionHistoryResponseSchema: z.ZodObject<{
|
|
81
|
+
sessionId: z.ZodString;
|
|
82
|
+
observations: z.ZodArray<z.ZodObject<{
|
|
83
|
+
sequence: z.ZodNumber;
|
|
84
|
+
elapsedMs: z.ZodNumber;
|
|
85
|
+
clientObservedAt: z.ZodNullable<z.ZodString>;
|
|
86
|
+
connectionState: z.ZodEnum<{
|
|
87
|
+
readonly Disconnected: "disconnected";
|
|
88
|
+
readonly Connecting: "connecting";
|
|
89
|
+
readonly Connected: "connected";
|
|
90
|
+
readonly Reconnecting: "reconnecting";
|
|
91
|
+
readonly SignalReconnecting: "signalReconnecting";
|
|
92
|
+
}>;
|
|
93
|
+
localQuality: z.ZodEnum<{
|
|
94
|
+
readonly Excellent: "excellent";
|
|
95
|
+
readonly Good: "good";
|
|
96
|
+
readonly Poor: "poor";
|
|
97
|
+
readonly Lost: "lost";
|
|
98
|
+
readonly Unknown: "unknown";
|
|
99
|
+
}>;
|
|
100
|
+
audioQuality: z.ZodNullable<z.ZodEnum<{
|
|
101
|
+
readonly Excellent: "excellent";
|
|
102
|
+
readonly Good: "good";
|
|
103
|
+
readonly Poor: "poor";
|
|
104
|
+
readonly Lost: "lost";
|
|
105
|
+
readonly Unknown: "unknown";
|
|
106
|
+
}>>;
|
|
107
|
+
videoQuality: z.ZodNullable<z.ZodEnum<{
|
|
108
|
+
readonly Excellent: "excellent";
|
|
109
|
+
readonly Good: "good";
|
|
110
|
+
readonly Poor: "poor";
|
|
111
|
+
readonly Lost: "lost";
|
|
112
|
+
readonly Unknown: "unknown";
|
|
113
|
+
}>>;
|
|
114
|
+
}, z.core.$strict>>;
|
|
115
|
+
}, z.core.$strict>;
|
|
116
|
+
type ConnectionHistoryObservation = z.infer<typeof connectionHistoryObservationSchema>;
|
|
117
|
+
type ConnectionHistoryGrant = z.infer<typeof connectionHistoryGrantSchema>;
|
|
118
|
+
type ConnectionHistoryUpload = z.infer<typeof connectionHistoryUploadSchema>;
|
|
119
|
+
type ConnectionHistoryResponse = z.infer<typeof connectionHistoryResponseSchema>;
|
|
120
|
+
|
|
121
|
+
export { CONNECTION_HISTORY_RETENTION_MS, type ConnectionHistoryGrant, type ConnectionHistoryObservation, type ConnectionHistoryResponse, type ConnectionHistoryUpload, MAX_CONNECTION_HISTORY_BATCH, MAX_CONNECTION_HISTORY_OBSERVATIONS, connectionHistoryGrantSchema, connectionHistoryObservationSchema, connectionHistoryResponseSchema, connectionHistoryUploadSchema };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CONNECTION_HISTORY_RETENTION_MS, MAX_CONNECTION_HISTORY_BATCH, MAX_CONNECTION_HISTORY_OBSERVATIONS, connectionHistoryGrantSchema, connectionHistoryObservationSchema, connectionHistoryResponseSchema, connectionHistoryUploadSchema } from './chunk-MCIXU6XP.js';
|
package/dist/express.d.ts
CHANGED
package/dist/express.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createProxyHandler } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { createProxyHandler } from './chunk-27BB4DQ2.js';
|
|
2
|
+
import './chunk-OESXLLQB.js';
|
|
3
|
+
import './chunk-MCIXU6XP.js';
|
|
3
4
|
|
|
4
5
|
// ../proxy/src/express.ts
|
|
5
6
|
function realtimeAvatarExpress(config) {
|
package/dist/hono.d.ts
CHANGED
package/dist/hono.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createProxyHandler } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { createProxyHandler } from './chunk-27BB4DQ2.js';
|
|
2
|
+
import './chunk-OESXLLQB.js';
|
|
3
|
+
import './chunk-MCIXU6XP.js';
|
|
3
4
|
|
|
4
5
|
// ../proxy/src/hono.ts
|
|
5
6
|
function realtimeAvatarHono(config) {
|
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 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 ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-
|
|
2
|
-
export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as RecordingArtifactStatus, x as RecordingMode, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-
|
|
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 ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-BnlnrYgN.js';
|
|
2
|
+
export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as RecordingArtifactStatus, x as RecordingMode, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-BnlnrYgN.js';
|
|
3
|
+
import { ConnectionHistoryResponse } from './connection-history.js';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
6
|
interface RealtimeAvatarOptions {
|
|
@@ -271,6 +272,8 @@ declare class RealtimeAvatar {
|
|
|
271
272
|
getRecording(recordingId: string): Promise<RecordingArtifact>;
|
|
272
273
|
/** Renewable playback access. Keep recordingId in storage; URLs expire at expiresAt. */
|
|
273
274
|
getRecordingAccess(recordingId: string): Promise<RecordingAccessResponse>;
|
|
275
|
+
/** Read one session's bounded LiveKit connection history. Requires `usage:read`. */
|
|
276
|
+
getConnectionHistory(sessionId: string): Promise<ConnectionHistoryResponse>;
|
|
274
277
|
creditBalance(): Promise<CreditBalance>;
|
|
275
278
|
}
|
|
276
279
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-OESXLLQB.js';
|
|
2
|
+
import './chunk-MCIXU6XP.js';
|
package/dist/nextjs.d.ts
CHANGED
package/dist/nextjs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createProxyHandler } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { createProxyHandler } from './chunk-27BB4DQ2.js';
|
|
2
|
+
import './chunk-OESXLLQB.js';
|
|
3
|
+
import './chunk-MCIXU6XP.js';
|
|
3
4
|
|
|
4
5
|
// ../proxy/src/nextjs.ts
|
|
5
6
|
function createRealtimeAvatarRoute(config) {
|
|
@@ -220,6 +220,7 @@ declare const liveKitSessionRequestSchema: z.ZodObject<{
|
|
|
220
220
|
secret: z.ZodString;
|
|
221
221
|
}, z.core.$strict>>;
|
|
222
222
|
clientMetadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
223
|
+
connectionHistory: z.ZodOptional<z.ZodBoolean>;
|
|
223
224
|
}, z.core.$strict>;
|
|
224
225
|
declare const liveKitSessionGrantSchema: z.ZodObject<{
|
|
225
226
|
recording: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -271,6 +272,11 @@ declare const liveKitSessionGrantSchema: z.ZodObject<{
|
|
|
271
272
|
recording_unavailable: "recording_unavailable";
|
|
272
273
|
}>;
|
|
273
274
|
}, z.core.$strict>], "status">>;
|
|
275
|
+
connection_history: z.ZodOptional<z.ZodObject<{
|
|
276
|
+
endpoint: z.ZodString;
|
|
277
|
+
token: z.ZodString;
|
|
278
|
+
expiresAt: z.ZodString;
|
|
279
|
+
}, z.core.$strict>>;
|
|
274
280
|
status: z.ZodDefault<z.ZodLiteral<"ready">>;
|
|
275
281
|
session_id: z.ZodString;
|
|
276
282
|
room_name: z.ZodString;
|
|
@@ -291,9 +297,9 @@ declare const liveKitSessionGrantSchema: z.ZodObject<{
|
|
|
291
297
|
declare const sessionEndReasonSchema: z.ZodEnum<{
|
|
292
298
|
idle: "idle";
|
|
293
299
|
failed: "failed";
|
|
300
|
+
disconnected: "disconnected";
|
|
294
301
|
user_ended: "user_ended";
|
|
295
302
|
session_cap: "session_cap";
|
|
296
|
-
disconnected: "disconnected";
|
|
297
303
|
out_of_credits: "out_of_credits";
|
|
298
304
|
agent_ended: "agent_ended";
|
|
299
305
|
}>;
|
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 AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-DmJVj18Z.js';
|
|
5
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-DmJVj18Z.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';
|
package/dist/react-native.js
CHANGED
|
@@ -1426,6 +1426,33 @@ z.object({
|
|
|
1426
1426
|
url: z.string().url(),
|
|
1427
1427
|
expiresAt: z.string().datetime({ offset: true })
|
|
1428
1428
|
}).strict();
|
|
1429
|
+
var ConnectionQuality2 = { Excellent: "excellent", Good: "good", Poor: "poor", Lost: "lost", Unknown: "unknown" };
|
|
1430
|
+
var ConnectionState4 = { Disconnected: "disconnected", Connecting: "connecting", Connected: "connected", Reconnecting: "reconnecting", SignalReconnecting: "signalReconnecting" };
|
|
1431
|
+
var MAX_CONNECTION_HISTORY_OBSERVATIONS = 240;
|
|
1432
|
+
var MAX_CONNECTION_HISTORY_BATCH = 32;
|
|
1433
|
+
var quality = z.enum(ConnectionQuality2);
|
|
1434
|
+
var connectionHistoryObservationSchema = z.object({
|
|
1435
|
+
sequence: z.number().int().min(1).max(MAX_CONNECTION_HISTORY_OBSERVATIONS),
|
|
1436
|
+
elapsedMs: z.number().int().min(0).max(864e5),
|
|
1437
|
+
clientObservedAt: z.string().datetime({ offset: true }).nullable(),
|
|
1438
|
+
connectionState: z.enum(ConnectionState4),
|
|
1439
|
+
localQuality: quality,
|
|
1440
|
+
audioQuality: quality.nullable(),
|
|
1441
|
+
videoQuality: quality.nullable()
|
|
1442
|
+
}).strict();
|
|
1443
|
+
var connectionHistoryGrantSchema = z.object({
|
|
1444
|
+
endpoint: z.string().url().startsWith("https://"),
|
|
1445
|
+
token: z.string().min(32).max(4096),
|
|
1446
|
+
expiresAt: z.string().datetime({ offset: true })
|
|
1447
|
+
}).strict();
|
|
1448
|
+
z.object({
|
|
1449
|
+
sessionId: z.string().min(1).max(200),
|
|
1450
|
+
observations: z.array(connectionHistoryObservationSchema).min(1).max(MAX_CONNECTION_HISTORY_BATCH)
|
|
1451
|
+
}).strict();
|
|
1452
|
+
z.object({
|
|
1453
|
+
sessionId: z.string().min(1).max(200),
|
|
1454
|
+
observations: z.array(connectionHistoryObservationSchema).max(MAX_CONNECTION_HISTORY_OBSERVATIONS)
|
|
1455
|
+
}).strict();
|
|
1429
1456
|
|
|
1430
1457
|
// ../client/src/wire.ts
|
|
1431
1458
|
var DEFAULT_AVATAR_ID = "maria";
|
|
@@ -1589,7 +1616,8 @@ z.object({
|
|
|
1589
1616
|
render_backend: renderBackendSchema.optional(),
|
|
1590
1617
|
support_edits: sessionSupportEditsSchema.optional(),
|
|
1591
1618
|
transcript_webhook: transcriptWebhookSchema.optional(),
|
|
1592
|
-
client_metadata: clientMetadataSchema.optional()
|
|
1619
|
+
client_metadata: clientMetadataSchema.optional(),
|
|
1620
|
+
connection_history: z.boolean().optional()
|
|
1593
1621
|
}).strict().superRefine((value, ctx) => {
|
|
1594
1622
|
if (value.support_edits && value.render_backend === "generative") {
|
|
1595
1623
|
ctx.addIssue({
|
|
@@ -1654,10 +1682,12 @@ z.object({
|
|
|
1654
1682
|
renderBackend: renderBackendSchema.optional(),
|
|
1655
1683
|
supportEdits: sessionSupportEditsSchema.optional(),
|
|
1656
1684
|
transcriptWebhook: transcriptWebhookSchema.optional(),
|
|
1657
|
-
clientMetadata: clientMetadataSchema.optional()
|
|
1685
|
+
clientMetadata: clientMetadataSchema.optional(),
|
|
1686
|
+
connectionHistory: z.boolean().optional()
|
|
1658
1687
|
}).strict();
|
|
1659
1688
|
z.object({
|
|
1660
1689
|
recording: recordingArtifactSchema.optional(),
|
|
1690
|
+
connection_history: connectionHistoryGrantSchema.optional(),
|
|
1661
1691
|
status: z.literal("ready").default("ready"),
|
|
1662
1692
|
session_id: z.string().min(1),
|
|
1663
1693
|
room_name: z.string().min(1),
|
|
@@ -1770,6 +1800,95 @@ function nextBehaviorSnapshot(prev, frame) {
|
|
|
1770
1800
|
return next;
|
|
1771
1801
|
}
|
|
1772
1802
|
|
|
1803
|
+
// ../client/src/react/connection-history.ts
|
|
1804
|
+
function createConnectionHistoryCollector(input) {
|
|
1805
|
+
const fetcher = input.fetch ?? ((request, init) => globalThis.fetch(request, init));
|
|
1806
|
+
const wallMs = input.clock?.wallMs ?? Date.now;
|
|
1807
|
+
const monotonicMs = input.clock?.monotonicMs ?? (() => globalThis.performance?.now() ?? Date.now());
|
|
1808
|
+
const startedAt = monotonicMs();
|
|
1809
|
+
const wallStartedAt = wallMs();
|
|
1810
|
+
const queue2 = [];
|
|
1811
|
+
let sequence = 0;
|
|
1812
|
+
let scheduled = false;
|
|
1813
|
+
let flushing = null;
|
|
1814
|
+
let disposed = false;
|
|
1815
|
+
let lastSnapshot = null;
|
|
1816
|
+
function enqueue(details) {
|
|
1817
|
+
if (disposed || details === null || sequence >= MAX_CONNECTION_HISTORY_OBSERVATIONS) return;
|
|
1818
|
+
const elapsedMs = Math.max(0, Math.min(864e5, Math.round(monotonicMs() - startedAt)));
|
|
1819
|
+
const nextSnapshot = {
|
|
1820
|
+
connectionState: details.connectionState,
|
|
1821
|
+
localQuality: details.localQuality,
|
|
1822
|
+
audioQuality: details.audio?.publisherQuality ?? null,
|
|
1823
|
+
videoQuality: details.video?.publisherQuality ?? null
|
|
1824
|
+
};
|
|
1825
|
+
const prior = lastSnapshot;
|
|
1826
|
+
if (prior && prior.connectionState === nextSnapshot.connectionState && prior.localQuality === nextSnapshot.localQuality && prior.audioQuality === nextSnapshot.audioQuality && prior.videoQuality === nextSnapshot.videoQuality) return;
|
|
1827
|
+
lastSnapshot = nextSnapshot;
|
|
1828
|
+
const value = {
|
|
1829
|
+
sequence: sequence + 1,
|
|
1830
|
+
elapsedMs,
|
|
1831
|
+
clientObservedAt: new Date(wallStartedAt + elapsedMs).toISOString(),
|
|
1832
|
+
...nextSnapshot
|
|
1833
|
+
};
|
|
1834
|
+
sequence = value.sequence;
|
|
1835
|
+
queue2.push(value);
|
|
1836
|
+
if (queue2.length >= MAX_CONNECTION_HISTORY_BATCH) void flush();
|
|
1837
|
+
else scheduleFlush();
|
|
1838
|
+
}
|
|
1839
|
+
function scheduleFlush() {
|
|
1840
|
+
if (scheduled || disposed) return;
|
|
1841
|
+
scheduled = true;
|
|
1842
|
+
queueMicrotask(() => {
|
|
1843
|
+
scheduled = false;
|
|
1844
|
+
void flush();
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
async function send(batch) {
|
|
1848
|
+
if (Date.parse(input.grant.expiresAt) <= wallMs()) return;
|
|
1849
|
+
const payload = { sessionId: input.sessionId, observations: batch };
|
|
1850
|
+
const retries = Math.max(0, Math.min(2, input.maxRetries ?? 2));
|
|
1851
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
1852
|
+
try {
|
|
1853
|
+
if (Date.parse(input.grant.expiresAt) <= wallMs()) return;
|
|
1854
|
+
const response = await fetcher(input.grant.endpoint, {
|
|
1855
|
+
method: "POST",
|
|
1856
|
+
headers: { authorization: `Bearer ${input.grant.token}`, "content-type": "application/json" },
|
|
1857
|
+
body: JSON.stringify(payload),
|
|
1858
|
+
signal: AbortSignal.timeout(5e3)
|
|
1859
|
+
});
|
|
1860
|
+
if (response.ok) return;
|
|
1861
|
+
if (response.status < 500 && response.status !== 429) return;
|
|
1862
|
+
await response.body?.cancel().catch(() => {
|
|
1863
|
+
});
|
|
1864
|
+
} catch {
|
|
1865
|
+
}
|
|
1866
|
+
if (attempt < retries) await new Promise((resolve) => setTimeout(resolve, 100 * 2 ** attempt));
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
async function flush() {
|
|
1870
|
+
if (queue2.length === 0) return;
|
|
1871
|
+
if (flushing) return flushing;
|
|
1872
|
+
flushing = (async () => {
|
|
1873
|
+
try {
|
|
1874
|
+
while (queue2.length) {
|
|
1875
|
+
const batch = queue2.splice(0, MAX_CONNECTION_HISTORY_BATCH);
|
|
1876
|
+
await send(batch);
|
|
1877
|
+
}
|
|
1878
|
+
} finally {
|
|
1879
|
+
flushing = null;
|
|
1880
|
+
}
|
|
1881
|
+
})();
|
|
1882
|
+
return flushing;
|
|
1883
|
+
}
|
|
1884
|
+
async function dispose() {
|
|
1885
|
+
disposed = true;
|
|
1886
|
+
await flush();
|
|
1887
|
+
queue2.length = 0;
|
|
1888
|
+
}
|
|
1889
|
+
return { enqueue, flush, dispose };
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1773
1892
|
// ../client/src/react/session-lifecycle.ts
|
|
1774
1893
|
function phaseForReason(reason) {
|
|
1775
1894
|
switch (reason) {
|
|
@@ -2244,11 +2363,35 @@ function SessionLifecycleRoomBridge({
|
|
|
2244
2363
|
const prevTranscriptionCountRef = useRef(0);
|
|
2245
2364
|
const audio = assistant.audioTrack;
|
|
2246
2365
|
const video = assistant.videoTrack;
|
|
2247
|
-
const
|
|
2366
|
+
const connectionHistoryGrant = lifecycle.grant?.connection_history;
|
|
2367
|
+
const detailsEnabled = (onConnectionDetailsChange !== void 0 || connectionHistoryGrant !== void 0) && lifecycle.grant !== null;
|
|
2248
2368
|
const detailsSessionId = lifecycle.grant?.session_id;
|
|
2369
|
+
const connectionHistoryRef = useRef(null);
|
|
2249
2370
|
const updateDetailsRef = useRef(null);
|
|
2250
2371
|
useEffect(() => {
|
|
2251
|
-
|
|
2372
|
+
const sessionId = detailsSessionId;
|
|
2373
|
+
if (!sessionId || !connectionHistoryGrant) {
|
|
2374
|
+
connectionHistoryRef.current = null;
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
const collector = createConnectionHistoryCollector({ sessionId, grant: connectionHistoryGrant });
|
|
2378
|
+
connectionHistoryRef.current = collector;
|
|
2379
|
+
return () => {
|
|
2380
|
+
if (connectionHistoryRef.current === collector) connectionHistoryRef.current = null;
|
|
2381
|
+
void collector.dispose();
|
|
2382
|
+
};
|
|
2383
|
+
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2384
|
+
useEffect(() => {
|
|
2385
|
+
const collector = connectionHistoryRef.current;
|
|
2386
|
+
if (!collector || typeof window === "undefined") return;
|
|
2387
|
+
const flush = () => {
|
|
2388
|
+
void collector.flush();
|
|
2389
|
+
};
|
|
2390
|
+
window.addEventListener("pagehide", flush, true);
|
|
2391
|
+
return () => window.removeEventListener("pagehide", flush, true);
|
|
2392
|
+
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2393
|
+
useEffect(() => {
|
|
2394
|
+
if (!detailsEnabled || !onConnectionDetailsChange && !connectionHistoryGrant) return;
|
|
2252
2395
|
let callback = onConnectionDetailsChange;
|
|
2253
2396
|
let audioSource = audio;
|
|
2254
2397
|
let videoSource = video;
|
|
@@ -2256,8 +2399,9 @@ function SessionLifecycleRoomBridge({
|
|
|
2256
2399
|
let pending = false;
|
|
2257
2400
|
let previous;
|
|
2258
2401
|
const deliver = (details) => {
|
|
2402
|
+
connectionHistoryRef.current?.enqueue(details);
|
|
2259
2403
|
try {
|
|
2260
|
-
void Promise.resolve(callback(details)).catch(() => {
|
|
2404
|
+
if (onConnectionDetailsChange) void Promise.resolve(callback?.(details)).catch(() => {
|
|
2261
2405
|
});
|
|
2262
2406
|
} catch {
|
|
2263
2407
|
}
|
|
@@ -2315,7 +2459,7 @@ function SessionLifecycleRoomBridge({
|
|
|
2315
2459
|
};
|
|
2316
2460
|
}, [room, detailsSessionId, detailsEnabled]);
|
|
2317
2461
|
useEffect(() => {
|
|
2318
|
-
|
|
2462
|
+
updateDetailsRef.current?.(onConnectionDetailsChange, audio, video);
|
|
2319
2463
|
}, [
|
|
2320
2464
|
onConnectionDetailsChange,
|
|
2321
2465
|
detailsEnabled ? audio?.participant : void 0,
|
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RegisteredTool, ToolRegistration } from './tools.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { ah as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-
|
|
4
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aL as AvatarVideoSurface, aM as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as NETWORK_QUALITY_POLICY, aR as NetworkQualityStatus, aS as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aT as RealtimeAvatarCapacityError, aU as RealtimeAvatarLiveKitRoom, aV as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aW as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
3
|
+
import { ah as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-DmJVj18Z.js';
|
|
4
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aL as AvatarVideoSurface, aM as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as NETWORK_QUALITY_POLICY, aR as NetworkQualityStatus, aS as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aT as RealtimeAvatarCapacityError, aU as RealtimeAvatarLiveKitRoom, aV as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aW as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-DmJVj18Z.js';
|
|
5
5
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '@livekit/components-react';
|
package/dist/react.js
CHANGED
|
@@ -1960,6 +1960,33 @@ z.object({
|
|
|
1960
1960
|
url: z.string().url(),
|
|
1961
1961
|
expiresAt: z.string().datetime({ offset: true })
|
|
1962
1962
|
}).strict();
|
|
1963
|
+
var ConnectionQuality2 = { Excellent: "excellent", Good: "good", Poor: "poor", Lost: "lost", Unknown: "unknown" };
|
|
1964
|
+
var ConnectionState4 = { Disconnected: "disconnected", Connecting: "connecting", Connected: "connected", Reconnecting: "reconnecting", SignalReconnecting: "signalReconnecting" };
|
|
1965
|
+
var MAX_CONNECTION_HISTORY_OBSERVATIONS = 240;
|
|
1966
|
+
var MAX_CONNECTION_HISTORY_BATCH = 32;
|
|
1967
|
+
var quality = z.enum(ConnectionQuality2);
|
|
1968
|
+
var connectionHistoryObservationSchema = z.object({
|
|
1969
|
+
sequence: z.number().int().min(1).max(MAX_CONNECTION_HISTORY_OBSERVATIONS),
|
|
1970
|
+
elapsedMs: z.number().int().min(0).max(864e5),
|
|
1971
|
+
clientObservedAt: z.string().datetime({ offset: true }).nullable(),
|
|
1972
|
+
connectionState: z.enum(ConnectionState4),
|
|
1973
|
+
localQuality: quality,
|
|
1974
|
+
audioQuality: quality.nullable(),
|
|
1975
|
+
videoQuality: quality.nullable()
|
|
1976
|
+
}).strict();
|
|
1977
|
+
var connectionHistoryGrantSchema = z.object({
|
|
1978
|
+
endpoint: z.string().url().startsWith("https://"),
|
|
1979
|
+
token: z.string().min(32).max(4096),
|
|
1980
|
+
expiresAt: z.string().datetime({ offset: true })
|
|
1981
|
+
}).strict();
|
|
1982
|
+
z.object({
|
|
1983
|
+
sessionId: z.string().min(1).max(200),
|
|
1984
|
+
observations: z.array(connectionHistoryObservationSchema).min(1).max(MAX_CONNECTION_HISTORY_BATCH)
|
|
1985
|
+
}).strict();
|
|
1986
|
+
z.object({
|
|
1987
|
+
sessionId: z.string().min(1).max(200),
|
|
1988
|
+
observations: z.array(connectionHistoryObservationSchema).max(MAX_CONNECTION_HISTORY_OBSERVATIONS)
|
|
1989
|
+
}).strict();
|
|
1963
1990
|
|
|
1964
1991
|
// ../client/src/wire.ts
|
|
1965
1992
|
var DEFAULT_AVATAR_ID = "maria";
|
|
@@ -2123,7 +2150,8 @@ z.object({
|
|
|
2123
2150
|
render_backend: renderBackendSchema.optional(),
|
|
2124
2151
|
support_edits: sessionSupportEditsSchema.optional(),
|
|
2125
2152
|
transcript_webhook: transcriptWebhookSchema.optional(),
|
|
2126
|
-
client_metadata: clientMetadataSchema.optional()
|
|
2153
|
+
client_metadata: clientMetadataSchema.optional(),
|
|
2154
|
+
connection_history: z.boolean().optional()
|
|
2127
2155
|
}).strict().superRefine((value, ctx) => {
|
|
2128
2156
|
if (value.support_edits && value.render_backend === "generative") {
|
|
2129
2157
|
ctx.addIssue({
|
|
@@ -2188,10 +2216,12 @@ z.object({
|
|
|
2188
2216
|
renderBackend: renderBackendSchema.optional(),
|
|
2189
2217
|
supportEdits: sessionSupportEditsSchema.optional(),
|
|
2190
2218
|
transcriptWebhook: transcriptWebhookSchema.optional(),
|
|
2191
|
-
clientMetadata: clientMetadataSchema.optional()
|
|
2219
|
+
clientMetadata: clientMetadataSchema.optional(),
|
|
2220
|
+
connectionHistory: z.boolean().optional()
|
|
2192
2221
|
}).strict();
|
|
2193
2222
|
z.object({
|
|
2194
2223
|
recording: recordingArtifactSchema.optional(),
|
|
2224
|
+
connection_history: connectionHistoryGrantSchema.optional(),
|
|
2195
2225
|
status: z.literal("ready").default("ready"),
|
|
2196
2226
|
session_id: z.string().min(1),
|
|
2197
2227
|
room_name: z.string().min(1),
|
|
@@ -2304,6 +2334,95 @@ function nextBehaviorSnapshot(prev, frame) {
|
|
|
2304
2334
|
return next;
|
|
2305
2335
|
}
|
|
2306
2336
|
|
|
2337
|
+
// ../client/src/react/connection-history.ts
|
|
2338
|
+
function createConnectionHistoryCollector(input) {
|
|
2339
|
+
const fetcher = input.fetch ?? ((request, init) => globalThis.fetch(request, init));
|
|
2340
|
+
const wallMs = input.clock?.wallMs ?? Date.now;
|
|
2341
|
+
const monotonicMs = input.clock?.monotonicMs ?? (() => globalThis.performance?.now() ?? Date.now());
|
|
2342
|
+
const startedAt = monotonicMs();
|
|
2343
|
+
const wallStartedAt = wallMs();
|
|
2344
|
+
const queue2 = [];
|
|
2345
|
+
let sequence = 0;
|
|
2346
|
+
let scheduled = false;
|
|
2347
|
+
let flushing = null;
|
|
2348
|
+
let disposed = false;
|
|
2349
|
+
let lastSnapshot = null;
|
|
2350
|
+
function enqueue(details) {
|
|
2351
|
+
if (disposed || details === null || sequence >= MAX_CONNECTION_HISTORY_OBSERVATIONS) return;
|
|
2352
|
+
const elapsedMs = Math.max(0, Math.min(864e5, Math.round(monotonicMs() - startedAt)));
|
|
2353
|
+
const nextSnapshot = {
|
|
2354
|
+
connectionState: details.connectionState,
|
|
2355
|
+
localQuality: details.localQuality,
|
|
2356
|
+
audioQuality: details.audio?.publisherQuality ?? null,
|
|
2357
|
+
videoQuality: details.video?.publisherQuality ?? null
|
|
2358
|
+
};
|
|
2359
|
+
const prior = lastSnapshot;
|
|
2360
|
+
if (prior && prior.connectionState === nextSnapshot.connectionState && prior.localQuality === nextSnapshot.localQuality && prior.audioQuality === nextSnapshot.audioQuality && prior.videoQuality === nextSnapshot.videoQuality) return;
|
|
2361
|
+
lastSnapshot = nextSnapshot;
|
|
2362
|
+
const value = {
|
|
2363
|
+
sequence: sequence + 1,
|
|
2364
|
+
elapsedMs,
|
|
2365
|
+
clientObservedAt: new Date(wallStartedAt + elapsedMs).toISOString(),
|
|
2366
|
+
...nextSnapshot
|
|
2367
|
+
};
|
|
2368
|
+
sequence = value.sequence;
|
|
2369
|
+
queue2.push(value);
|
|
2370
|
+
if (queue2.length >= MAX_CONNECTION_HISTORY_BATCH) void flush();
|
|
2371
|
+
else scheduleFlush();
|
|
2372
|
+
}
|
|
2373
|
+
function scheduleFlush() {
|
|
2374
|
+
if (scheduled || disposed) return;
|
|
2375
|
+
scheduled = true;
|
|
2376
|
+
queueMicrotask(() => {
|
|
2377
|
+
scheduled = false;
|
|
2378
|
+
void flush();
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
async function send(batch) {
|
|
2382
|
+
if (Date.parse(input.grant.expiresAt) <= wallMs()) return;
|
|
2383
|
+
const payload = { sessionId: input.sessionId, observations: batch };
|
|
2384
|
+
const retries = Math.max(0, Math.min(2, input.maxRetries ?? 2));
|
|
2385
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
2386
|
+
try {
|
|
2387
|
+
if (Date.parse(input.grant.expiresAt) <= wallMs()) return;
|
|
2388
|
+
const response = await fetcher(input.grant.endpoint, {
|
|
2389
|
+
method: "POST",
|
|
2390
|
+
headers: { authorization: `Bearer ${input.grant.token}`, "content-type": "application/json" },
|
|
2391
|
+
body: JSON.stringify(payload),
|
|
2392
|
+
signal: AbortSignal.timeout(5e3)
|
|
2393
|
+
});
|
|
2394
|
+
if (response.ok) return;
|
|
2395
|
+
if (response.status < 500 && response.status !== 429) return;
|
|
2396
|
+
await response.body?.cancel().catch(() => {
|
|
2397
|
+
});
|
|
2398
|
+
} catch {
|
|
2399
|
+
}
|
|
2400
|
+
if (attempt < retries) await new Promise((resolve) => setTimeout(resolve, 100 * 2 ** attempt));
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
async function flush() {
|
|
2404
|
+
if (queue2.length === 0) return;
|
|
2405
|
+
if (flushing) return flushing;
|
|
2406
|
+
flushing = (async () => {
|
|
2407
|
+
try {
|
|
2408
|
+
while (queue2.length) {
|
|
2409
|
+
const batch = queue2.splice(0, MAX_CONNECTION_HISTORY_BATCH);
|
|
2410
|
+
await send(batch);
|
|
2411
|
+
}
|
|
2412
|
+
} finally {
|
|
2413
|
+
flushing = null;
|
|
2414
|
+
}
|
|
2415
|
+
})();
|
|
2416
|
+
return flushing;
|
|
2417
|
+
}
|
|
2418
|
+
async function dispose() {
|
|
2419
|
+
disposed = true;
|
|
2420
|
+
await flush();
|
|
2421
|
+
queue2.length = 0;
|
|
2422
|
+
}
|
|
2423
|
+
return { enqueue, flush, dispose };
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2307
2426
|
// ../client/src/react/session-lifecycle.ts
|
|
2308
2427
|
function phaseForReason(reason) {
|
|
2309
2428
|
switch (reason) {
|
|
@@ -2783,11 +2902,35 @@ function SessionLifecycleRoomBridge({
|
|
|
2783
2902
|
const prevTranscriptionCountRef = useRef(0);
|
|
2784
2903
|
const audio = assistant.audioTrack;
|
|
2785
2904
|
const video = assistant.videoTrack;
|
|
2786
|
-
const
|
|
2905
|
+
const connectionHistoryGrant = lifecycle.grant?.connection_history;
|
|
2906
|
+
const detailsEnabled = (onConnectionDetailsChange !== void 0 || connectionHistoryGrant !== void 0) && lifecycle.grant !== null;
|
|
2787
2907
|
const detailsSessionId = lifecycle.grant?.session_id;
|
|
2908
|
+
const connectionHistoryRef = useRef(null);
|
|
2788
2909
|
const updateDetailsRef = useRef(null);
|
|
2789
2910
|
useEffect(() => {
|
|
2790
|
-
|
|
2911
|
+
const sessionId = detailsSessionId;
|
|
2912
|
+
if (!sessionId || !connectionHistoryGrant) {
|
|
2913
|
+
connectionHistoryRef.current = null;
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
const collector = createConnectionHistoryCollector({ sessionId, grant: connectionHistoryGrant });
|
|
2917
|
+
connectionHistoryRef.current = collector;
|
|
2918
|
+
return () => {
|
|
2919
|
+
if (connectionHistoryRef.current === collector) connectionHistoryRef.current = null;
|
|
2920
|
+
void collector.dispose();
|
|
2921
|
+
};
|
|
2922
|
+
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2923
|
+
useEffect(() => {
|
|
2924
|
+
const collector = connectionHistoryRef.current;
|
|
2925
|
+
if (!collector || typeof window === "undefined") return;
|
|
2926
|
+
const flush = () => {
|
|
2927
|
+
void collector.flush();
|
|
2928
|
+
};
|
|
2929
|
+
window.addEventListener("pagehide", flush, true);
|
|
2930
|
+
return () => window.removeEventListener("pagehide", flush, true);
|
|
2931
|
+
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2932
|
+
useEffect(() => {
|
|
2933
|
+
if (!detailsEnabled || !onConnectionDetailsChange && !connectionHistoryGrant) return;
|
|
2791
2934
|
let callback = onConnectionDetailsChange;
|
|
2792
2935
|
let audioSource = audio;
|
|
2793
2936
|
let videoSource = video;
|
|
@@ -2795,8 +2938,9 @@ function SessionLifecycleRoomBridge({
|
|
|
2795
2938
|
let pending = false;
|
|
2796
2939
|
let previous;
|
|
2797
2940
|
const deliver = (details) => {
|
|
2941
|
+
connectionHistoryRef.current?.enqueue(details);
|
|
2798
2942
|
try {
|
|
2799
|
-
void Promise.resolve(callback(details)).catch(() => {
|
|
2943
|
+
if (onConnectionDetailsChange) void Promise.resolve(callback?.(details)).catch(() => {
|
|
2800
2944
|
});
|
|
2801
2945
|
} catch {
|
|
2802
2946
|
}
|
|
@@ -2854,7 +2998,7 @@ function SessionLifecycleRoomBridge({
|
|
|
2854
2998
|
};
|
|
2855
2999
|
}, [room, detailsSessionId, detailsEnabled]);
|
|
2856
3000
|
useEffect(() => {
|
|
2857
|
-
|
|
3001
|
+
updateDetailsRef.current?.(onConnectionDetailsChange, audio, video);
|
|
2858
3002
|
}, [
|
|
2859
3003
|
onConnectionDetailsChange,
|
|
2860
3004
|
detailsEnabled ? audio?.participant : void 0,
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, RealtimeAvatarOptions, StartCallOptions, clipLibraryDeclarationSchema, verifyTranscript } from './index.js';
|
|
2
|
-
export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, w as RecordingArtifactStatus, x as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-
|
|
2
|
+
export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, w as RecordingArtifactStatus, x as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-BnlnrYgN.js';
|
|
3
|
+
import './connection-history.js';
|
|
3
4
|
import 'zod';
|
package/dist/server.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-OESXLLQB.js';
|
|
2
|
+
import './chunk-MCIXU6XP.js';
|
package/dist/tanstack-start.d.ts
CHANGED
package/dist/tanstack-start.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createProxyHandler } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { createProxyHandler } from './chunk-27BB4DQ2.js';
|
|
2
|
+
import './chunk-OESXLLQB.js';
|
|
3
|
+
import './chunk-MCIXU6XP.js';
|
|
3
4
|
|
|
4
5
|
// src/tanstack-start.ts
|
|
5
6
|
function realtimeAvatarServerRoute(config) {
|
|
@@ -163,6 +163,7 @@ interface components {
|
|
|
163
163
|
* @enum {string}
|
|
164
164
|
*/
|
|
165
165
|
recording?: "off" | "audio" | "video" | "audio_video";
|
|
166
|
+
connection_history?: boolean;
|
|
166
167
|
client_metadata?: {
|
|
167
168
|
[key: string]: string;
|
|
168
169
|
};
|
|
@@ -241,6 +242,13 @@ interface components {
|
|
|
241
242
|
/** @enum {string} */
|
|
242
243
|
errorCode: "recording_failed" | "recording_unavailable";
|
|
243
244
|
};
|
|
245
|
+
readonly connection_history?: {
|
|
246
|
+
/** Format: starts_with */
|
|
247
|
+
endpoint: string;
|
|
248
|
+
token: string;
|
|
249
|
+
/** Format: date-time */
|
|
250
|
+
expiresAt: string;
|
|
251
|
+
};
|
|
244
252
|
};
|
|
245
253
|
LiveKitCapacitySnapshot: {
|
|
246
254
|
capacity_pool: string;
|
|
@@ -573,6 +581,20 @@ interface components {
|
|
|
573
581
|
/** Format: date-time */
|
|
574
582
|
expiresAt: string;
|
|
575
583
|
};
|
|
584
|
+
ConnectionHistoryResponse: {
|
|
585
|
+
sessionId: string;
|
|
586
|
+
observations: {
|
|
587
|
+
sequence: number;
|
|
588
|
+
elapsedMs: number;
|
|
589
|
+
clientObservedAt: string | null;
|
|
590
|
+
/** @enum {string} */
|
|
591
|
+
connectionState: "disconnected" | "connecting" | "connected" | "reconnecting" | "signalReconnecting";
|
|
592
|
+
/** @enum {string} */
|
|
593
|
+
localQuality: "excellent" | "good" | "poor" | "lost" | "unknown";
|
|
594
|
+
audioQuality: ("excellent" | "good" | "poor" | "lost" | "unknown") | null;
|
|
595
|
+
videoQuality: ("excellent" | "good" | "poor" | "lost" | "unknown") | null;
|
|
596
|
+
}[];
|
|
597
|
+
};
|
|
576
598
|
ListAvatarsResponse: {
|
|
577
599
|
data: {
|
|
578
600
|
id: string;
|
|
@@ -1090,6 +1112,8 @@ type VideoPolicy = {
|
|
|
1090
1112
|
};
|
|
1091
1113
|
/** What YOUR SERVER decides about a call. Never accept any of this from a browser. */
|
|
1092
1114
|
interface CallPolicy {
|
|
1115
|
+
/** Ask the platform to grant the SDK's optional LiveKit connection history collector. */
|
|
1116
|
+
connectionHistory?: boolean;
|
|
1093
1117
|
/** Optional server recording policy. Omitted means off; obtain user consent before enabling. */
|
|
1094
1118
|
recording?: RecordingMode;
|
|
1095
1119
|
/** Her behavior contract — who she is and how she speaks. Max 8000 chars. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CallMode, a as CallPolicy } from './types-
|
|
1
|
+
import { C as CallMode, a as CallPolicy } from './types-BnlnrYgN.js';
|
|
2
2
|
|
|
3
3
|
/** The three things a caller can ask the proxy to do. Gate on these, not on URLs. */
|
|
4
4
|
type ProxyOperation = "connect" | "end" | "avatars" | "credits";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "realtime-avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Realtime Avatar SDK. `realtime-avatar` and the route adapters hold your API key and are server-only; `realtime-avatar/react`, `/browser` and `/tools` never can — importing a server entry into a browser build throws at bundle time.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "The Influence Company",
|
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"types": "./dist/recording.d.ts",
|
|
90
90
|
"default": "./dist/recording.js"
|
|
91
91
|
},
|
|
92
|
+
"./connection-history": {
|
|
93
|
+
"types": "./dist/connection-history.d.ts",
|
|
94
|
+
"default": "./dist/connection-history.js"
|
|
95
|
+
},
|
|
92
96
|
"./tools": {
|
|
93
97
|
"types": "./dist/tools.d.ts",
|
|
94
98
|
"default": "./dist/tools.js"
|