@voxevolv/client 0.3.6 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  All notable changes to `@voxevolv/client` are recorded here.
4
4
 
5
+ ## 0.3.8 - Unreleased
6
+
7
+ - Increase the default startup deadline from 65 to 90 seconds, registering about
8
+ 85 seconds for backend recovery and extending the final readiness wait to 50
9
+ seconds. Custom shorter budgets remain supported; older clients keep their
10
+ 65-second fallback until upgraded.
11
+
12
+ - Coordinate bounded initial agent recovery through `/sessions/{id}/startup`,
13
+ preserving the overall startup deadline across browser rejoin attempts.
14
+ Requires the startup-recovery migration, compatible workers, and control endpoint.
15
+
16
+ - Deliver bounded diagnostic batches with stable IDs, durable receipts, and capped
17
+ background retries; report dropped evidence and flush on page hiding/shutdown.
18
+ Requires the updated backend diagnostic endpoint and migration before rollout.
19
+
20
+ - Keep healthy calls connected when context commands or transfers time out.
21
+ - Retry the newest silent replacement context in the background with capped
22
+ exponential backoff, preserving caller deadlines and explicit rejection errors.
23
+ - Complete connection recovery after hello, agent readiness, and audio; restore
24
+ context independently without replaying speech requests after a delivery timeout.
25
+ - Back off streamed-context retransmission and cancel background delivery on shutdown.
26
+ - Prevent overlapping uploads after transfer timeout, rejoin, or a late acknowledgement,
27
+ and preserve retained-value identity when retrying restored context.
28
+
29
+ ## 0.3.7 - 2026-09-25
30
+
31
+ - Recover a missed session ending from durable events when room-token renewal
32
+ returns 409, preserving the recorded reason instead of reporting a connection failure.
33
+ - Complete once when the agent leaves after an ending announcement, even if the
34
+ browser stays connected to the room; also handle announcements arriving after departure.
35
+ - Keep terminal provider errors as failures when replay includes worker shutdown events.
36
+ - Preserve the first announced ending reason when later teardown events arrive.
37
+ - Cancel manual rejoin on session completion or explicit disconnect, including
38
+ stalled token response bodies; reject rejoin after the session has ended.
39
+ - Restrict retryable session-error handling to active startup attempts; established
40
+ sessions release media and stay failed even when the provider error is retryable.
41
+ - Keep control announcements separate from agent sequence tracking, avoiding
42
+ false gap reports while preserving replay of genuinely missing agent events.
43
+
5
44
  ## 0.3.6 - 2026-09-23
6
45
 
7
46
  - Enable initial connection retries by default for both `RealtimeSession` and
package/README.md CHANGED
@@ -127,15 +127,39 @@ await session.connect({ waitForRemoteAudio: false });
127
127
 
128
128
  ## Initial connection retries
129
129
 
130
- Startup retries are enabled by default in SDK 0.3.6 for both `new RealtimeSession()`
130
+ Startup retries have been enabled by default since SDK 0.3.6 for both `new RealtimeSession()`
131
131
  and `RealtimeSession.create()`. Omit `startupRetry` or pass `true` to retry a
132
132
  session that has not connected successfully yet. The default policy allows up to
133
- three total attempts with 15, 20, and 25-second readiness budgets, waits one second
134
- before attempt two and three
135
- seconds before attempt three, and enforces a 65-second overall deadline. The
136
- overall deadline also includes room connection, token renewal, microphone
133
+ three total attempts with 15, 20, and 50-second readiness budgets, waits one second
134
+ before attempt two and three seconds before attempt three, and enforces a
135
+ 90-second overall deadline in SDK 0.3.8. The overall deadline also includes room
136
+ connection, token renewal, microphone
137
137
  publication, the client hello, and remote-audio readiness.
138
138
 
139
+ SDK 0.3.8 coordinates initial agent recovery through the session-scoped
140
+ `POST /sessions/{id}/startup` endpoint. Registration is included in the overall
141
+ startup deadline. It reserves 10% of the remaining budget, capped at five seconds,
142
+ and gives the backend at most 85 seconds.
143
+ The request limit is the smaller of that reserve and three seconds; a five-second
144
+ custom startup budget therefore retains about 4.5 seconds on the server.
145
+ Repeated registrations and room-token requests never renew the backend deadline.
146
+ Applications proxying the API must forward this route as well.
147
+
148
+ The backend inspects stalled startup after ten seconds of candidate presence.
149
+ A failed or expired dispatch can be replaced at most three times, with at least
150
+ ten seconds between attempts. A pending/running dispatch gets a twenty-second
151
+ startup allowance; a recent heartbeat or existing agent prevents replacement.
152
+ The longer window gives three replacements more time to fit; scheduling and
153
+ network delays can still reduce the number of attempts.
154
+ The server also enrolls older SDK clients at session creation and discovers their
155
+ first candidate join through LiveKit polling, without requiring webhooks. Older
156
+ clients retain a 65-second fallback window to match their browser deadline;
157
+ upgrading the SDK enables the longer window.
158
+ Brief browser absence pauses repair until it rejoins the same room. The browser
159
+ still uses the normal SDK startup retry policy, including disconnect/rejoin gaps.
160
+ A dispatch API success means requested, not ready: readiness is recorded separately.
161
+ There is no guaranteed recovery time or guarantee that a healthy worker exists.
162
+
139
163
  Set `startupRetry: false` in the constructor or `create()` options for a single
140
164
  startup attempt using the `readyTimeoutMs` supplied through `connect()` or the
141
165
  constructor defaults. This does not disable `autoRejoin` after a successful connection.
@@ -172,9 +196,9 @@ startupRetry: {
172
196
  attempts: [
173
197
  { readyTimeoutMs: 15_000 },
174
198
  { delayBeforeMs: 1_000, readyTimeoutMs: 20_000 },
175
- { delayBeforeMs: 3_000, readyTimeoutMs: 25_000 },
199
+ { delayBeforeMs: 3_000, readyTimeoutMs: 50_000 },
176
200
  ],
177
- timeoutMs: 65_000,
201
+ timeoutMs: 90_000,
178
202
  }
179
203
  ```
180
204
 
@@ -187,8 +211,8 @@ credentials after a `401`. A `session.error` explicitly marked
187
211
 
188
212
  ## Recovery, rejoin, and connection quality
189
213
 
190
- With `@voxevolv/client@0.3.2` or newer, set `autoRejoin: true` to let the SDK recover
191
- when an agent leaves, its worker changes, a context command times out, or LiveKit
214
+ Set `autoRejoin: true` to let the SDK recover
215
+ when an agent leaves, its worker changes, or LiveKit
192
216
  exhausts its transport reconnect. Automatic recovery runs only after the session has
193
217
  connected successfully, never after an explicit `disconnect()`, `end()`, or
194
218
  terminal LiveKit removal. It waits for browser connectivity, obtains a fresh
@@ -198,8 +222,9 @@ Automatic rejoin has a default 180-second deadline, including time spent offline
198
222
  Use `autoRejoin: { timeoutMs: 180_000 }` to configure it; an explicit `maxAttempts`
199
223
  can stop retries earlier. This renews the room connection for the **same session**.
200
224
  It never creates a replacement assessment/session. `connected` is reported only
201
- after the client hello (including tool handlers), agent readiness, remote audio
202
- (unless opted out), and replacement-context restoration succeed.
225
+ after the client hello (including tool handlers), agent readiness, and remote audio
226
+ (unless opted out) succeed. Replacement context synchronizes in the background;
227
+ its failure cannot prevent a healthy call from reporting connected.
203
228
 
204
229
  The updated server protects replacement-worker startup with a three-minute
205
230
  participant grace period. It restores up to the latest 200 committed transcript
@@ -217,6 +242,24 @@ it restores accepted values with `respond: false`. Append updates are not queued
217
242
  or replayed during recovery because repeating them could duplicate input. Updates
218
243
  already in flight may have reached the server even if their acknowledgment was lost.
219
244
 
245
+ Starting in 0.3.8, context command and transfer timeouts never trigger a rejoin.
246
+ The update promise still rejects at its delivery deadline (20 seconds by default),
247
+ so applications can report the failure or submit a fresh timer value. The SDK
248
+ retains the newest silent replacement value per key for background delivery,
249
+ with delays of roughly 1, 2, 4, then 8 seconds, jittered and capped at 8 seconds.
250
+ New submissions replace queued values without bypassing backoff. Command retries
251
+ within a delivery attempt use the same backoff and message ID. Retries pause during
252
+ connection recovery and stop when the session ends, fails, or disconnects.
253
+ If an upload times out while its LiveKit writer is still running, subsequent
254
+ uploads for that key wait for the writer to settle, including across rejoin.
255
+ The pinned writer API has no public cancellation method; this guard prevents
256
+ stalled transfers from accumulating while audio and other context keys continue.
257
+ Invalid or non-retryable rejected updates are discarded. Append updates and
258
+ `respond: true` updates are not automatically replayed after their deadline:
259
+ an acknowledgement can be lost after the worker has already applied the update
260
+ or requested speech. Restoring a retained value after a real rejoin uses
261
+ `respond: false`. Applications remain responsible for the freshness of timer text.
262
+
220
263
  Keep the existing `RealtimeSession` instance during recovery, register tools on
221
264
  that instance, and use `onStateChange`, `onStartupAttempt`, and `onRecovery` for
222
265
  UI. Avoid application retry loops that create new sessions. Older clients remain
@@ -251,16 +294,31 @@ session.onConnectionQuality((quality) => {
251
294
  `waitForState(states, timeoutMs, { signal })` is available for advanced flows
252
295
  that need to await a bounded set of lifecycle states.
253
296
 
254
- In version 0.3.4, every recovery event includes a typed `trigger`, such as
255
- `context_command_timeout`, `livekit_disconnected`, `agent_disconnected`, or
256
- `worker_replaced`. Context timeouts also include the safe `messageId`,
257
- `contextKey`, and `timeoutMs` correlation fields. The SDK keeps the latest 128
258
- content-free transport and command entries in memory. It sends a throttled,
259
- best-effort report only after a slow operation, rejection, failure, timeout, or
260
- reconnect. Reports never include context text, screenshots, tokens, or raw URLs,
261
- and reporting failures never affect the call. A trigger received during the
262
- throttle window is retained for one trailing report, and each diagnostics request
263
- stops waiting after five seconds so a stuck endpoint cannot block later evidence.
297
+ Every recovery event includes a typed `trigger`, such as `livekit_disconnected`,
298
+ `agent_disconnected`, or `worker_replaced`. Context timeouts are recorded in
299
+ diagnostics with message, context-key, and timeout correlation; they no longer
300
+ emit recovery events. The SDK keeps up to 128 content-free entries in a 64 KiB
301
+ recent-history buffer. Slow operations, rejections, failures, timeouts, recovery,
302
+ page hiding, and session shutdown trigger HTTP diagnostic delivery independently
303
+ of the call transport. Reports never include context text, screenshots, tokens,
304
+ or raw URLs, and reporting failures never affect the call.
305
+
306
+ Starting in 0.3.8, reports are immutable batches of at most 16 KiB with report IDs,
307
+ SDK-instance IDs, increasing entry sequences, a wall-clock start anchor, and
308
+ monotonic relative timings. The SDK accepts delivery only when the backend returns
309
+ that batch's report ID after saving it. One upload runs at a time, each with a
310
+ five-second deadline (including the receipt body) and `keepalive`. Failed uploads
311
+ retry with exponential backoff and jitter, respecting the server's throttle delay.
312
+ Acknowledged entries are not uploaded again. Pending batches and buffered entries
313
+ expire after five minutes; cumulative `dropped_entries` records overflow, expiry,
314
+ and permanent rejection in subsequent reports. This queue is memory-only: browser
315
+ termination can still lose unsent evidence.
316
+
317
+ Deploy the backend migration and diagnostic endpoint before this SDK. The endpoint
318
+ continues accepting older SDK reports, saves new batches idempotently, and returns
319
+ `429` with `retry_after_ms` when throttled. Stored reports are retained for seven
320
+ days, with bounded cleanup by the existing control jobs process. Worker diagnostic
321
+ logging is unchanged in this release.
264
322
 
265
323
  Manual `rejoin()` remains available. It obtains a fresh room token, disconnects
266
324
  any underlying room connection, and reconnects with the original microphone or
@@ -280,6 +338,7 @@ enabled by default), or a same-origin proxy base that forwards only:
280
338
  - `POST /sessions/{id}/room-tokens`
281
339
  - `GET /sessions/{id}/events`
282
340
  - `POST /sessions/{id}/diagnostics`
341
+ - `POST /sessions/{id}/startup`
283
342
  - `DELETE /sessions/{id}`
284
343
 
285
344
  The proxy must forward the browser's `Authorization: Bearer vsa_...` header. It