@voxevolv/client 0.1.0 → 0.3.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/CHANGELOG.md +36 -0
- package/README.md +67 -11
- package/dist/browser/index.js +6 -6
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/index.js.sha384 +1 -1
- package/dist/browser/manifest.json +1 -1
- package/dist/generated/protocol-codecs.d.ts.map +1 -1
- package/dist/generated/protocol-codecs.js +41 -0
- package/dist/generated/protocol-codecs.js.map +1 -1
- package/dist/index.d.ts +61 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +530 -52
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@voxevolv/client` are recorded here.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.3.0 - 2026-07-24
|
|
8
|
+
|
|
9
|
+
- Add opt-in SDK-owned recovery with `autoRejoin`, bounded backoff, terminal
|
|
10
|
+
disconnect-reason handling, and the `resuming` connection state.
|
|
11
|
+
- Surface signal-only LiveKit reconnects instead of skipping directly from
|
|
12
|
+
`connected` to readiness restoration.
|
|
13
|
+
- Add `hasConnectedBefore`, `onRecovery()`, `onConnectionQuality()`, and
|
|
14
|
+
`waitForState()`.
|
|
15
|
+
- Make rejoin disconnect based on the underlying LiveKit room state so a
|
|
16
|
+
failed post-reconnect hello cannot leave a connected room in the way.
|
|
17
|
+
- Add configurable lifecycle fetch credentials with a `same-origin` default,
|
|
18
|
+
preserving cookie-authenticated same-origin proxies while omitting cookies
|
|
19
|
+
on direct cross-origin calls.
|
|
20
|
+
- End an in-flight recovery cleanly when the server emits `session.ended`
|
|
21
|
+
instead of leaving the wrapper state at `resuming`.
|
|
22
|
+
- Preserve the outer `rejoin` recovery when late LiveKit reconnect events
|
|
23
|
+
arrive during that attempt, preventing them from moving the wrapper back to
|
|
24
|
+
`reconnecting` and blocking the replacement connection.
|
|
25
|
+
- Preserve the user's microphone mute state across manual and automatic full
|
|
26
|
+
rejoin so recovery never returns with a previously muted microphone enabled.
|
|
27
|
+
- Keep commands pending when the first post-reconnect data publish is rejected,
|
|
28
|
+
allowing the existing retry loop to deliver them once the data channel is
|
|
29
|
+
writable.
|
|
30
|
+
|
|
31
|
+
## 0.2.0 - 2026-07-20
|
|
32
|
+
|
|
33
|
+
- Add `session.outputStream`: a stable `MediaStream` that always holds the
|
|
34
|
+
agent's current remote audio tracks across track arrival, reconnects, and
|
|
35
|
+
rejoin.
|
|
36
|
+
- `connect()` now also waits for the first remote agent audio track (within
|
|
37
|
+
the same `readyTimeoutMs` budget) before resolving, so media is flowing when
|
|
38
|
+
connect resolves. Pass `waitForRemoteAudio: false` to restore the previous
|
|
39
|
+
signaling-only readiness.
|
|
40
|
+
|
|
5
41
|
## 0.1.0 - 2026-07-18
|
|
6
42
|
|
|
7
43
|
- Add application-owned audio-track publication and remote-audio access.
|
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Browsers without a build step can use the versioned bundle after publication:
|
|
|
26
26
|
```html
|
|
27
27
|
<script type="module">
|
|
28
28
|
import { RealtimeSession } from
|
|
29
|
-
"https://cdn.jsdelivr.net/npm/@voxevolv/client@0.
|
|
29
|
+
"https://cdn.jsdelivr.net/npm/@voxevolv/client@0.3.0/dist/browser/index.js";
|
|
30
30
|
</script>
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -38,9 +38,10 @@ VoxEvolv session without exposing an organization API key:
|
|
|
38
38
|
```ts
|
|
39
39
|
const session = await RealtimeSession.create({
|
|
40
40
|
endpoint: "/api/voice-session",
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
apiBase: "/
|
|
41
|
+
// Use the hosted API directly when its lifecycle CORS policy is public.
|
|
42
|
+
// A same-origin lifecycle proxy remains supported.
|
|
43
|
+
apiBase: "https://YOUR_VOXEVOLV_HOST/v1",
|
|
44
|
+
autoRejoin: true,
|
|
44
45
|
tools: {
|
|
45
46
|
present_attachment: (arguments_) => presentAttachment(arguments_),
|
|
46
47
|
},
|
|
@@ -60,7 +61,8 @@ play remote audio:
|
|
|
60
61
|
|
|
61
62
|
```ts
|
|
62
63
|
const session = new RealtimeSession(credentials, {
|
|
63
|
-
connect: { apiBase: "/
|
|
64
|
+
connect: { apiBase: "https://YOUR_VOXEVOLV_HOST/v1" },
|
|
65
|
+
autoRejoin: true,
|
|
64
66
|
});
|
|
65
67
|
await session.connect({ microphone: true });
|
|
66
68
|
```
|
|
@@ -100,11 +102,59 @@ a native `MediaStreamTrack` and single-track `MediaStream` for recording,
|
|
|
100
102
|
metering, or another application-owned audio graph. Both listener registration
|
|
101
103
|
methods return an unsubscribe function.
|
|
102
104
|
|
|
103
|
-
##
|
|
105
|
+
## Agent audio readiness
|
|
104
106
|
|
|
105
|
-
`
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
By default `connect()` resolves only after the agent reported readiness *and*
|
|
108
|
+
the first remote agent audio track arrived, both within the same
|
|
109
|
+
`readyTimeoutMs` budget (15 s by default). Agent media is therefore already
|
|
110
|
+
flowing when `connect()` resolves, so recording or metering set up right after
|
|
111
|
+
`connect()` does not race track arrival.
|
|
112
|
+
|
|
113
|
+
`session.outputStream` is a stable `MediaStream` available from session
|
|
114
|
+
creation. The stream object never changes; remote agent audio tracks are added
|
|
115
|
+
when they arrive and removed when they end, including across `rejoin()` and
|
|
116
|
+
reconnects. Note that Web Audio's `createMediaStreamSource()` requires the
|
|
117
|
+
stream to already contain an audio track, so audio-graph consumers should
|
|
118
|
+
still attach inside `onRemoteAudioTrack`.
|
|
119
|
+
|
|
120
|
+
Applications that intentionally run without agent audio can opt out:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
await session.connect({ waitForRemoteAudio: false });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Recovery, rejoin, and connection quality
|
|
127
|
+
|
|
128
|
+
Set `autoRejoin: true` to let the SDK own recovery after LiveKit exhausts its
|
|
129
|
+
transport-level reconnect. Automatic recovery runs only after the session has
|
|
130
|
+
connected successfully, never after an explicit `disconnect()`, `end()`, or
|
|
131
|
+
terminal LiveKit removal. It waits for browser connectivity, obtains a fresh
|
|
132
|
+
room token, and retries with bounded backoff.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
session.onStateChange((state) => {
|
|
136
|
+
// reconnecting: LiveKit is restoring transport
|
|
137
|
+
// resuming: VoxEvolv is restoring readiness with a fresh connection
|
|
138
|
+
renderConnectionState(state);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
session.onRecovery(({ status, strategy, attempt, error }) => {
|
|
142
|
+
recordRecovery({ status, strategy, attempt, error });
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
session.onConnectionQuality((quality) => {
|
|
146
|
+
renderCallQuality(quality);
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`session.hasConnectedBefore` distinguishes recovery from initial setup.
|
|
151
|
+
`waitForState(states, timeoutMs, { signal })` is available for advanced flows
|
|
152
|
+
that need to await a bounded set of lifecycle states.
|
|
153
|
+
|
|
154
|
+
Manual `rejoin()` remains available. It obtains a fresh room token, disconnects
|
|
155
|
+
any underlying room connection, and reconnects with the original microphone or
|
|
156
|
+
application-owned track choice. A managed microphone that the user muted with
|
|
157
|
+
`setMicrophoneEnabled(false)` remains muted after rejoin.
|
|
108
158
|
|
|
109
159
|
```ts
|
|
110
160
|
await session.rejoin();
|
|
@@ -113,8 +163,8 @@ await session.end();
|
|
|
113
163
|
|
|
114
164
|
`RealtimeSession.create()` requires `apiBase` because rejoin, durable replay,
|
|
115
165
|
and scoped ending happen after the application-owned creation request. Set it
|
|
116
|
-
to either an explicit absolute VoxEvolv `/v1` base
|
|
117
|
-
|
|
166
|
+
to either an explicit absolute VoxEvolv `/v1` base (browser lifecycle access is
|
|
167
|
+
enabled by default), or a same-origin proxy base that forwards only:
|
|
118
168
|
|
|
119
169
|
- `POST /sessions/{id}/room-tokens`
|
|
120
170
|
- `GET /sessions/{id}/events`
|
|
@@ -123,6 +173,12 @@ the application origin, or a same-origin proxy base that forwards only:
|
|
|
123
173
|
The proxy must forward the browser's `Authorization: Bearer vsa_...` header. It
|
|
124
174
|
must not replace that credential with an organization API key.
|
|
125
175
|
|
|
176
|
+
Lifecycle fetches default to `credentials: "same-origin"`. This sends cookies
|
|
177
|
+
to a same-origin proxy but not to an absolute cross-origin VoxEvolv API. Set
|
|
178
|
+
`lifecycleCredentials` only when a custom proxy has a different credential
|
|
179
|
+
policy; cross-origin `include` requires an exact-origin credentialed CORS
|
|
180
|
+
configuration and is incompatible with wildcard CORS.
|
|
181
|
+
|
|
126
182
|
`end()` uses the browser-safe `vsa_...` credential to end only that session and
|
|
127
183
|
then leaves the LiveKit room. Pass `endEndpoint` to the constructor or
|
|
128
184
|
`end({ endpoint })` when application policy requires a backend completion route.
|