@voxevolv/client 0.3.16 → 0.3.17

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/dist/index.js CHANGED
@@ -7,7 +7,8 @@ import {
7
7
  Room,
8
8
  RoomEvent,
9
9
  RpcError,
10
- Track
10
+ Track,
11
+ version as LIVEKIT_VERSION
11
12
  } from "./vendor/livekit-client.esm.mjs";
12
13
  import {
13
14
  createClientMessage,
@@ -23,8 +24,10 @@ import {
23
24
  import { ContextDeliveryError, contextRetryDelay, ReplacementContextQueue } from "./context-queue.js";
24
25
  import {
25
26
  ClientDiagnosticBuffer,
27
+ diagnosticId,
26
28
  DiagnosticDeliveryError
27
29
  } from "./diagnostics.js";
30
+ import { observeConnectionTransport } from "./connection-diagnostics.js";
28
31
  import { observeRpcTransport } from "./rpc-transport-diagnostics.js";
29
32
  import { Presentations } from "./presentations.js";
30
33
  import { TranscriptStore } from "./transcripts.js";
@@ -51,7 +54,7 @@ import {
51
54
  decodeContextUpdatedPayload,
52
55
  decodeRealtimeEvent
53
56
  } from "./generated/protocol-codecs.js";
54
- var SDK_VERSION = "0.3.16";
57
+ var SDK_VERSION = "0.3.17";
55
58
  var CLIENT_HELLO_TIMEOUT_MS = 3e4;
56
59
  var RECOVERY_BUFFER_STALL_MS = 5e3;
57
60
  var RECOVERY_BUFFER_POLL_MS = 500;
@@ -178,6 +181,8 @@ var RealtimeSession = class _RealtimeSession {
178
181
  diagnosticLastSampleAt = 0;
179
182
  stopRpcDiagnostics;
180
183
  diagnosticEngine;
184
+ connectionDiagnostics;
185
+ diagnosticRecoveryId;
181
186
  presentations = new Presentations(
182
187
  (request) => this.room.localParticipant.performRpc(request),
183
188
  () => this.sessionEnded || ["disconnected", "failed"].includes(this.stateValue),
@@ -192,6 +197,10 @@ var RealtimeSession = class _RealtimeSession {
192
197
  this.recordDiagnostic({ operation: "browser_runtime", status: "succeeded", reason });
193
198
  this.flushDiagnostics(reason);
194
199
  };
200
+ onDiagnosticNetworkChange = (event) => {
201
+ this.recordDiagnostic({ operation: "browser_runtime", status: "succeeded", reason: `network_${event.type}` });
202
+ this.flushDiagnostics(`network_${event.type}`);
203
+ };
195
204
  onDiagnosticLifecycle = (event) => {
196
205
  this.recordDiagnostic({ operation: "browser_runtime", status: "succeeded", reason: event.type });
197
206
  this.flushDiagnostics(`page_${event.type}`);
@@ -214,6 +223,9 @@ var RealtimeSession = class _RealtimeSession {
214
223
  this.startupRetryOptions = resolveStartupRetryOptions(options.startupRetry);
215
224
  this.lifecycleCredentials = options.lifecycleCredentials ?? "same-origin";
216
225
  this.room = new Room({ adaptiveStream: true, dynacast: true });
226
+ this.room.voxevolvObserveEngine = () => {
227
+ this.startRpcDiagnostics();
228
+ };
217
229
  for (const [name, handler] of Object.entries(options.tools ?? {})) {
218
230
  this.registerTool(name, handler);
219
231
  }
@@ -709,6 +721,7 @@ var RealtimeSession = class _RealtimeSession {
709
721
  this.livekitResumeController = null;
710
722
  this.failRecovery(toError(error));
711
723
  this.recoveryStartedAt = null;
724
+ this.diagnosticRecoveryId = void 0;
712
725
  this.reconnectStartedAt = null;
713
726
  this.pendingReconnect = null;
714
727
  }
@@ -1117,6 +1130,8 @@ var RealtimeSession = class _RealtimeSession {
1117
1130
  if (state === "connecting" || state === "resuming") {
1118
1131
  this.startRpcDiagnostics();
1119
1132
  this.startDiagnosticLoopMonitor();
1133
+ globalThis.addEventListener?.("online", this.onDiagnosticNetworkChange);
1134
+ globalThis.addEventListener?.("offline", this.onDiagnosticNetworkChange);
1120
1135
  globalThis.document?.addEventListener?.("visibilitychange", this.onDiagnosticVisibilityChange);
1121
1136
  globalThis.document?.addEventListener?.("freeze", this.onDiagnosticLifecycle);
1122
1137
  globalThis.document?.addEventListener?.("resume", this.onDiagnosticLifecycle);
@@ -1126,6 +1141,11 @@ var RealtimeSession = class _RealtimeSession {
1126
1141
  this.diagnosticLoopTimer = void 0;
1127
1142
  this.diagnosticLoopDelayMs = void 0;
1128
1143
  this.diagnosticLoopHistory = [];
1144
+ this.connectionDiagnostics?.stop();
1145
+ this.connectionDiagnostics = void 0;
1146
+ this.diagnosticRecoveryId = void 0;
1147
+ globalThis.removeEventListener?.("online", this.onDiagnosticNetworkChange);
1148
+ globalThis.removeEventListener?.("offline", this.onDiagnosticNetworkChange);
1129
1149
  this.stopRpcDiagnostics?.();
1130
1150
  this.stopRpcDiagnostics = void 0;
1131
1151
  this.diagnosticEngine = void 0;
@@ -1166,13 +1186,22 @@ var RealtimeSession = class _RealtimeSession {
1166
1186
  }
1167
1187
  });
1168
1188
  this.room.on(RoomEvent.SignalConnected, () => this.startRpcDiagnostics());
1169
- this.room.on(RoomEvent.SignalReconnecting, () => this.handleLiveKitReconnecting());
1170
- this.room.on(RoomEvent.Reconnecting, () => this.handleLiveKitReconnecting());
1189
+ this.room.on(RoomEvent.SignalReconnecting, () => this.handleLiveKitReconnecting("signal_reconnecting"));
1190
+ this.room.on(RoomEvent.Reconnecting, () => this.handleLiveKitReconnecting("media_reconnecting"));
1171
1191
  this.room.on(RoomEvent.Reconnected, () => {
1172
1192
  this.startRpcDiagnostics();
1173
1193
  void this.handleLiveKitReconnected();
1174
1194
  });
1175
1195
  this.room.on(RoomEvent.Disconnected, (reason) => {
1196
+ if (!this.disconnectMode && !this.sessionEnded) {
1197
+ this.recordDiagnostic({
1198
+ operation: "connection_transport",
1199
+ status: "failed",
1200
+ reason: "room_disconnected",
1201
+ disconnect_reason: reason
1202
+ });
1203
+ this.flushDiagnostics("room_disconnected");
1204
+ }
1176
1205
  this.handleLiveKitDisconnected(reason);
1177
1206
  });
1178
1207
  this.room.on(RoomEvent.ConnectionStateChanged, (state) => {
@@ -1252,8 +1281,9 @@ var RealtimeSession = class _RealtimeSession {
1252
1281
  this.notifyListeners(this.listeners, value);
1253
1282
  });
1254
1283
  }
1255
- handleLiveKitReconnecting() {
1284
+ handleLiveKitReconnecting(trigger = "livekit_reconnecting") {
1256
1285
  if (this.sessionEnded || this.disconnectMode === "intentional" || this.terminalReplayController || ["disconnected", "failed"].includes(this.stateValue)) return;
1286
+ this.recordDiagnostic({ operation: "connection_transport", status: "started", reason: trigger });
1257
1287
  this.agentReady = false;
1258
1288
  if (this.autoRejoinPromise !== null || this.activeRecovery?.strategy === "rejoin" || this.disconnectMode === "rejoin") {
1259
1289
  this.setState("resuming");
@@ -1433,6 +1463,7 @@ var RealtimeSession = class _RealtimeSession {
1433
1463
  this.notifyListeners(this.endedListeners, event);
1434
1464
  }
1435
1465
  beginRecovery(strategy, attempt, details) {
1466
+ this.diagnosticRecoveryId ??= diagnosticId();
1436
1467
  this.recoveryStartedAt ??= Date.now();
1437
1468
  this.activeRecovery = { strategy, attempt, details };
1438
1469
  this.recordDiagnostic({
@@ -1465,6 +1496,7 @@ var RealtimeSession = class _RealtimeSession {
1465
1496
  });
1466
1497
  this.flushDiagnostics("recovery_completed");
1467
1498
  this.recoveryStartedAt = null;
1499
+ this.diagnosticRecoveryId = void 0;
1468
1500
  this.activeRecovery = null;
1469
1501
  this.notifyListeners(this.recoveryListeners, {
1470
1502
  status: "succeeded",
@@ -1572,6 +1604,7 @@ var RealtimeSession = class _RealtimeSession {
1572
1604
  this.livekitResumeController?.abort();
1573
1605
  this.livekitResumeController = null;
1574
1606
  this.recoveryStartedAt = null;
1607
+ this.diagnosticRecoveryId = void 0;
1575
1608
  this.autoRejoinController?.abort();
1576
1609
  this.autoRejoinController = null;
1577
1610
  this.manualRejoinController?.abort();
@@ -2025,6 +2058,12 @@ var RealtimeSession = class _RealtimeSession {
2025
2058
  if (!engine || this.stopRpcDiagnostics && this.diagnosticEngine === engine) return;
2026
2059
  this.stopRpcDiagnostics?.();
2027
2060
  this.diagnosticEngine = engine;
2061
+ this.connectionDiagnostics?.stop();
2062
+ this.connectionDiagnostics = observeConnectionTransport(engine, (entry) => {
2063
+ if (this.disconnectMode || this.sessionEnded || ["disconnected", "failed"].includes(this.stateValue)) return;
2064
+ this.recordDiagnostic(entry);
2065
+ this.flushDiagnostics("connection_transport");
2066
+ });
2028
2067
  this.stopRpcDiagnostics = observeRpcTransport(engine, (entry) => {
2029
2068
  this.recordDiagnostic(entry);
2030
2069
  this.flushDiagnostics("tool_rpc_transport");
@@ -2050,12 +2089,23 @@ var RealtimeSession = class _RealtimeSession {
2050
2089
  }
2051
2090
  }
2052
2091
  recordDiagnostic(entry) {
2092
+ if (entry.operation === "connection_transport") {
2093
+ this.diagnosticRecoveryId ??= diagnosticId();
2094
+ }
2053
2095
  const snapshot = {
2054
2096
  ...entry,
2097
+ recovery_id: this.diagnosticRecoveryId,
2098
+ connection_id: entry.connection_id ?? this.connectionId,
2099
+ participant_sid: this.room.localParticipant.sid || void 0,
2100
+ livekit_version: LIVEKIT_VERSION,
2101
+ browser_online: globalThis.navigator?.onLine,
2055
2102
  connection_state: this.stateValue,
2056
2103
  buffered_bytes: entry.buffered_bytes ?? this.reliableDataChannelBufferedBytes()
2057
2104
  };
2058
- if (["tool_rpc", "rpc_transport", "browser_runtime", "connection_recovery"].includes(entry.operation)) {
2105
+ if (["connection_transport", "connection_recovery"].includes(entry.operation)) {
2106
+ snapshot.transport_history ??= this.connectionDiagnostics?.snapshotHistory();
2107
+ }
2108
+ if (["tool_rpc", "rpc_transport", "browser_runtime", "connection_recovery", "connection_transport"].includes(entry.operation)) {
2059
2109
  snapshot.page_visibility = globalThis.document?.visibilityState;
2060
2110
  snapshot.active_context_transfers = this.activeContextTransfers;
2061
2111
  snapshot.active_context_bytes = this.activeContextBytes;