@voicethere/client 0.7.28 → 0.8.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 +26 -0
- package/dist/browser/audio-playback.d.ts +12 -0
- package/dist/browser/audio-playback.d.ts.map +1 -0
- package/dist/browser/audio-playback.js +28 -0
- package/dist/browser/audio-playback.js.map +1 -0
- package/dist/browser/audio-visualizer.d.ts +1 -0
- package/dist/browser/audio-visualizer.d.ts.map +1 -1
- package/dist/browser/audio-visualizer.js +30 -0
- package/dist/browser/audio-visualizer.js.map +1 -1
- package/dist/browser/browser-session.d.ts +8 -3
- package/dist/browser/browser-session.d.ts.map +1 -1
- package/dist/browser/browser-session.js +4 -0
- package/dist/browser/browser-session.js.map +1 -1
- package/dist/browser/browser-voice-session.d.ts +20 -3
- package/dist/browser/browser-voice-session.d.ts.map +1 -1
- package/dist/browser/browser-voice-session.js +65 -6
- package/dist/browser/browser-voice-session.js.map +1 -1
- package/dist/embed/config.d.ts +33 -0
- package/dist/embed/config.d.ts.map +1 -0
- package/dist/embed/config.js +204 -0
- package/dist/embed/config.js.map +1 -0
- package/dist/embed/index.d.ts +12 -7
- package/dist/embed/index.d.ts.map +1 -1
- package/dist/embed/index.js +177 -24
- package/dist/embed/index.js.map +1 -1
- package/dist/embed/presets.d.ts +27 -0
- package/dist/embed/presets.d.ts.map +1 -0
- package/dist/embed/presets.js +151 -0
- package/dist/embed/presets.js.map +1 -0
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## 0.8.0 — 2026-08-31
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Embed presets and CDN config** — `createVoiceThereWidget` supports `preset`, `position`, `launcherLabel`, and `greeting`. Brand `theme` colors overlay preset defaults. `createVoiceThereWidgetAsync` loads appearance from `configUrl` (no credentials); inline options override fetched JSON. Published config schema `VoiceThereWidgetConfigV1` rejects secret-like keys (`clientKey`, `token`, etc.). Presets: `pill-dark`, `pill-light`, `rounded-card`, `minimal-bar`, `voice-orb`.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Embed widget CDN config** — `createVoiceThereWidgetAsync` still mounts the launcher from inline options when `configUrl` is missing, unreachable, or returns invalid JSON; warns in the console instead of rejecting the promise.
|
|
14
|
+
- **Audio visualizer idle frame** — `attachAudioVisualizer().stop()` and ended MediaStream tracks now clear the canvas and draw a flat midline instead of freezing on the last analyser snapshot.
|
|
15
|
+
|
|
16
|
+
## 0.7.29 — 2026-08-28
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Inbound audio playback helpers** — `audio-playback.ts` exports `AudioPlaybackState`, `unlockAudioPlayback()`, and `createHiddenAudioElement()`. Voice sessions auto-create a hidden `<audio>` element when none is supplied; `getAudioPlaybackState()` and `unlockAudioPlayback()` expose autoplay-blocked state.
|
|
21
|
+
- **Embed widget mic notice** — After voice connect with denied/unavailable/synthetic microphone, the embed shows an amber notice and **Request microphone** button. **Tap to enable sound** appears when inbound playback is blocked.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **Embed inbound agent audio** — The embed widget now passes a hidden `<audio>` element and unlocks playback on Connect click so agent TTS can play without a live microphone.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Reconnect callbacks** — `onIceRecovery`, `onReconnecting`, and `onReconnected` accept an optional 2nd arg `VoiceSessionReconnectInfo` (`reason`, effective `iceTransportPolicy`) for E2E/load-test diagnostics.
|
|
30
|
+
|
|
5
31
|
## 0.7.28 — 2026-08-15
|
|
6
32
|
|
|
7
33
|
### Fixed
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type AudioPlaybackState = "idle" | "playing" | "blocked";
|
|
2
|
+
/**
|
|
3
|
+
* Attempt to start playback on an audio element (e.g. after user gesture or ontrack).
|
|
4
|
+
* Returns false on failure without throwing.
|
|
5
|
+
*/
|
|
6
|
+
export declare function unlockAudioPlayback(el: HTMLAudioElement): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Create a hidden autoplay audio element for inbound agent TTS when the caller
|
|
9
|
+
* does not supply one. Returns null when no DOM is available (Node runtime).
|
|
10
|
+
*/
|
|
11
|
+
export declare function createHiddenAudioElement(): HTMLAudioElement | null;
|
|
12
|
+
//# sourceMappingURL=audio-playback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-playback.d.ts","sourceRoot":"","sources":["../../src/browser/audio-playback.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhE;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,gBAAgB,GACnB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,gBAAgB,GAAG,IAAI,CAQlE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attempt to start playback on an audio element (e.g. after user gesture or ontrack).
|
|
3
|
+
* Returns false on failure without throwing.
|
|
4
|
+
*/
|
|
5
|
+
export async function unlockAudioPlayback(el) {
|
|
6
|
+
try {
|
|
7
|
+
await el.play();
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a hidden autoplay audio element for inbound agent TTS when the caller
|
|
16
|
+
* does not supply one. Returns null when no DOM is available (Node runtime).
|
|
17
|
+
*/
|
|
18
|
+
export function createHiddenAudioElement() {
|
|
19
|
+
if (typeof document === "undefined")
|
|
20
|
+
return null;
|
|
21
|
+
const el = document.createElement("audio");
|
|
22
|
+
el.autoplay = true;
|
|
23
|
+
el.setAttribute("playsinline", "");
|
|
24
|
+
el.style.display = "none";
|
|
25
|
+
document.body.append(el);
|
|
26
|
+
return el;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=audio-playback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-playback.js","sourceRoot":"","sources":["../../src/browser/audio-playback.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;IACnB,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACnC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzB,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -9,5 +9,6 @@ export type AudioVisualizer = {
|
|
|
9
9
|
stop: () => void;
|
|
10
10
|
resume: () => void;
|
|
11
11
|
};
|
|
12
|
+
export declare function drawIdleVisualizer(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, waveColor?: string): void;
|
|
12
13
|
export declare function attachAudioVisualizer(options: AudioVisualizerOptions): AudioVisualizer;
|
|
13
14
|
//# sourceMappingURL=audio-visualizer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-visualizer.d.ts","sourceRoot":"","sources":["../../src/browser/audio-visualizer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,
|
|
1
|
+
{"version":3,"file":"audio-visualizer.d.ts","sourceRoot":"","sources":["../../src/browser/audio-visualizer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,wBAAwB,EAC7B,MAAM,EAAE,iBAAiB,EACzB,SAAS,SAAY,GACpB,IAAI,CAUN;AAkBD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CA+GjB"}
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
export function drawIdleVisualizer(ctx, canvas, waveColor = "#38bdf8") {
|
|
2
|
+
const width = canvas.width;
|
|
3
|
+
const height = canvas.height;
|
|
4
|
+
ctx.clearRect(0, 0, width, height);
|
|
5
|
+
ctx.lineWidth = 2;
|
|
6
|
+
ctx.strokeStyle = waveColor;
|
|
7
|
+
ctx.beginPath();
|
|
8
|
+
ctx.moveTo(0, height / 2);
|
|
9
|
+
ctx.lineTo(width, height / 2);
|
|
10
|
+
ctx.stroke();
|
|
11
|
+
}
|
|
12
|
+
function getTappedMediaStream(mediaStream, audioElement) {
|
|
13
|
+
if (mediaStream)
|
|
14
|
+
return mediaStream;
|
|
15
|
+
if (audioElement?.srcObject instanceof MediaStream) {
|
|
16
|
+
return audioElement.srcObject;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function hasLiveAudioTrack(stream) {
|
|
21
|
+
if (!stream)
|
|
22
|
+
return false;
|
|
23
|
+
return stream.getAudioTracks().some((track) => track.readyState === "live");
|
|
24
|
+
}
|
|
1
25
|
export function attachAudioVisualizer(options) {
|
|
2
26
|
const { canvas, audioElement, mediaStream, waveColor = "#38bdf8", barColor = "#818cf8", } = options;
|
|
3
27
|
if (!audioElement && !mediaStream) {
|
|
@@ -45,6 +69,11 @@ export function attachAudioVisualizer(options) {
|
|
|
45
69
|
if (stopped)
|
|
46
70
|
return;
|
|
47
71
|
rafId = requestAnimationFrame(draw);
|
|
72
|
+
const tappedStream = getTappedMediaStream(mediaStream, audioElement);
|
|
73
|
+
if (tappedStream !== null && !hasLiveAudioTrack(tappedStream)) {
|
|
74
|
+
drawIdleVisualizer(ctx, canvas, waveColor);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
48
77
|
const width = canvas.width;
|
|
49
78
|
const height = canvas.height;
|
|
50
79
|
ctx.clearRect(0, 0, width, height);
|
|
@@ -78,6 +107,7 @@ export function attachAudioVisualizer(options) {
|
|
|
78
107
|
stop: () => {
|
|
79
108
|
stopped = true;
|
|
80
109
|
cancelAnimationFrame(rafId);
|
|
110
|
+
drawIdleVisualizer(ctx, canvas, waveColor);
|
|
81
111
|
void audioCtx.close();
|
|
82
112
|
},
|
|
83
113
|
resume: ensureRunning,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-visualizer.js","sourceRoot":"","sources":["../../src/browser/audio-visualizer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audio-visualizer.js","sourceRoot":"","sources":["../../src/browser/audio-visualizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,20 +17,24 @@ export type ConnectBrowserSessionOptions = {
|
|
|
17
17
|
onAgentAudioTrack?: BrowserVoiceSessionOptions["onAgentAudioTrack"];
|
|
18
18
|
reconnectPolicy?: import("./browser-voice-session.js").ReconnectPolicy;
|
|
19
19
|
maxAutoReconnectAttempts?: number;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
maxIceRecoveryAttempts?: number;
|
|
21
|
+
onIceRecovery?: import("./browser-voice-session.js").BrowserVoiceSessionOptions["onIceRecovery"];
|
|
22
|
+
onReconnecting?: import("./browser-voice-session.js").BrowserVoiceSessionOptions["onReconnecting"];
|
|
23
|
+
onReconnected?: import("./browser-voice-session.js").BrowserVoiceSessionOptions["onReconnected"];
|
|
22
24
|
onConnectionStatus?: (status: WebRtcConnectionStatus) => void;
|
|
23
25
|
iceTransportPolicy?: BrowserVoiceSessionOptions["iceTransportPolicy"];
|
|
24
26
|
onDiagnosticEvent?: BrowserVoiceSessionOptions["onDiagnosticEvent"];
|
|
25
27
|
/** Preferred audio input device for voice / voice+data sessions. */
|
|
26
28
|
audioInputDeviceId?: string;
|
|
29
|
+
/** Fired when inbound agent audio playback starts or is blocked by the browser. */
|
|
30
|
+
onAudioPlayback?: BrowserVoiceSessionOptions["onAudioPlayback"];
|
|
27
31
|
};
|
|
28
32
|
export type BrowserSession = BrowserVoiceSession & {
|
|
29
33
|
mode: BrowserSessionMode;
|
|
30
34
|
};
|
|
31
35
|
export declare function connectBrowserSession(options: ConnectBrowserSessionOptions): Promise<BrowserSession>;
|
|
32
36
|
export declare function connectDataSession(options: Omit<BrowserVoiceSessionOptions, "requestMic">): Promise<BrowserVoiceSession>;
|
|
33
|
-
export type { ReconnectPolicy } from "./browser-voice-session.js";
|
|
37
|
+
export type { ReconnectPolicy, VoiceSessionReconnectInfo, } from "./browser-voice-session.js";
|
|
34
38
|
export { connectBrowserChatSession } from "./browser-chat-session.js";
|
|
35
39
|
export { connectBrowserVoiceSession, VOICE_SYNC_CHANNEL_LABEL, VOICE_CONTROL_CHANNEL_LABEL, type BinaryMessageHandler, type SyncBinaryMessageHandler, type DataChannelKind, type BrowserVoiceSession, type BrowserVoiceSessionOptions, } from "./browser-voice-session.js";
|
|
36
40
|
export { startSession } from "./session-provision.js";
|
|
@@ -52,4 +56,5 @@ export type { VoiceSessionDiagnosticEvent, VoiceSessionDiagnosticHandler, } from
|
|
|
52
56
|
export { redactDiagnosticDetail } from "./voice-session-diagnostics.js";
|
|
53
57
|
export { CLIENT_CAPABILITIES, type ClientCapabilities, } from "./client-capabilities.js";
|
|
54
58
|
export { acquireAudioInput, createSyntheticMicStream, listAudioInputDevices, stopMicStream, type AudioInputDevice, type AudioInputState, } from "./microphone.js";
|
|
59
|
+
export { createHiddenAudioElement, unlockAudioPlayback, type AudioPlaybackState, } from "./audio-playback.js";
|
|
55
60
|
//# sourceMappingURL=browser-session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-session.d.ts","sourceRoot":"","sources":["../../src/browser/browser-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,sBAAsB,EAEvB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,cAAc,CAAC,EAAE,OAAO,sBAAsB,EAAE,mBAAmB,CAAC;IACpE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC9D,eAAe,CAAC,EAAE,0BAA0B,CAAC,iBAAiB,CAAC,CAAC;IAChE,mBAAmB,CAAC,EAAE,0BAA0B,CAAC,qBAAqB,CAAC,CAAC;IACxE,iBAAiB,CAAC,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;IACpE,eAAe,CAAC,EAAE,OAAO,4BAA4B,EAAE,eAAe,CAAC;IACvE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,
|
|
1
|
+
{"version":3,"file":"browser-session.d.ts","sourceRoot":"","sources":["../../src/browser/browser-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,12 +35,15 @@ export async function connectBrowserSession(options) {
|
|
|
35
35
|
onAgentAudioTrack: options.onAgentAudioTrack,
|
|
36
36
|
reconnectPolicy: options.reconnectPolicy,
|
|
37
37
|
maxAutoReconnectAttempts: options.maxAutoReconnectAttempts,
|
|
38
|
+
maxIceRecoveryAttempts: options.maxIceRecoveryAttempts,
|
|
39
|
+
onIceRecovery: options.onIceRecovery,
|
|
38
40
|
onReconnecting: options.onReconnecting,
|
|
39
41
|
onReconnected: options.onReconnected,
|
|
40
42
|
onConnectionStatus: options.onConnectionStatus,
|
|
41
43
|
iceTransportPolicy: options.iceTransportPolicy,
|
|
42
44
|
onDiagnosticEvent: options.onDiagnosticEvent,
|
|
43
45
|
audioInputDeviceId: requestMic ? options.audioInputDeviceId : undefined,
|
|
46
|
+
onAudioPlayback: options.onAudioPlayback,
|
|
44
47
|
});
|
|
45
48
|
return { ...session, mode: resolvedMode };
|
|
46
49
|
}
|
|
@@ -63,4 +66,5 @@ export { closePeerConnectionAwaitable, } from "./peer-connection-close.js";
|
|
|
63
66
|
export { redactDiagnosticDetail } from "./voice-session-diagnostics.js";
|
|
64
67
|
export { CLIENT_CAPABILITIES, } from "./client-capabilities.js";
|
|
65
68
|
export { acquireAudioInput, createSyntheticMicStream, listAudioInputDevices, stopMicStream, } from "./microphone.js";
|
|
69
|
+
export { createHiddenAudioElement, unlockAudioPlayback, } from "./audio-playback.js";
|
|
66
70
|
//# sourceMappingURL=browser-session.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-session.js","sourceRoot":"","sources":["../../src/browser/browser-session.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,0BAA0B,GAG3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,yBAAyB,GAE1B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-session.js","sourceRoot":"","sources":["../../src/browser/browser-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ import { type WebRtcRuntime } from "./webrtc-runtime.js";
|
|
|
7
7
|
import { type PeerCloseResult } from "./peer-connection-close.js";
|
|
8
8
|
import { type VoiceSessionDiagnosticHandler } from "./voice-session-diagnostics.js";
|
|
9
9
|
import { type AudioInputState } from "./microphone.js";
|
|
10
|
+
import { type AudioPlaybackState } from "./audio-playback.js";
|
|
11
|
+
export type { AudioPlaybackState } from "./audio-playback.js";
|
|
10
12
|
/**
|
|
11
13
|
* Native RTCPeerConnection rejects offers without `a=ice-ufrag` (empty or truncated SDP).
|
|
12
14
|
* Detect before setRemoteDescription so we can same-session reconnect instead of hanging.
|
|
@@ -24,6 +26,12 @@ export type BinaryMessageHandler = (data: ArrayBuffer) => void;
|
|
|
24
26
|
/** Fired for binary frames on voicethere-sync data channel. */
|
|
25
27
|
export type SyncBinaryMessageHandler = (data: ArrayBuffer) => void;
|
|
26
28
|
export type ReconnectPolicy = "same-session" | "new-session";
|
|
29
|
+
/** Passed as optional 2nd arg to same-session reconnect / ICE recovery callbacks. */
|
|
30
|
+
export type VoiceSessionReconnectInfo = {
|
|
31
|
+
reason: string;
|
|
32
|
+
/** Effective RTCConfiguration.iceTransportPolicy for the next/current PC. */
|
|
33
|
+
iceTransportPolicy?: "all" | "relay";
|
|
34
|
+
};
|
|
27
35
|
export type BrowserVoiceSessionOptions = {
|
|
28
36
|
credentials: SessionCredentials;
|
|
29
37
|
/**
|
|
@@ -95,13 +103,13 @@ export type BrowserVoiceSessionOptions = {
|
|
|
95
103
|
*/
|
|
96
104
|
iceRecoveryStuckCheckingMs?: number;
|
|
97
105
|
/** Fired when starting an ICE recovery attempt (not {@link onReconnecting}). */
|
|
98
|
-
onIceRecovery?: (attempt: number) => void;
|
|
99
|
-
onReconnecting?: (attempt: number) => void;
|
|
106
|
+
onIceRecovery?: (attempt: number, info?: VoiceSessionReconnectInfo) => void;
|
|
107
|
+
onReconnecting?: (attempt: number, info?: VoiceSessionReconnectInfo) => void;
|
|
100
108
|
/**
|
|
101
109
|
* Fired when same-session reconnect (auto or manual) reaches readiness again
|
|
102
110
|
* after the initial connect — not on first connect.
|
|
103
111
|
*/
|
|
104
|
-
onReconnected?: (attempt: number) => void;
|
|
112
|
+
onReconnected?: (attempt: number, info?: VoiceSessionReconnectInfo) => void;
|
|
105
113
|
/**
|
|
106
114
|
* Readiness gate for `waitForConnected()` / `getConnectionStatus().ready`.
|
|
107
115
|
* Defaults from `requestMic`: voice sessions wait for inbound+outbound audio tracks;
|
|
@@ -110,6 +118,8 @@ export type BrowserVoiceSessionOptions = {
|
|
|
110
118
|
readiness?: WebRtcReadinessProfile;
|
|
111
119
|
/** Fired whenever WebRTC connection readiness changes (signaling through media/DCs). */
|
|
112
120
|
onConnectionStatus?: (status: WebRtcConnectionStatus) => void;
|
|
121
|
+
/** Fired when inbound agent audio playback starts or is blocked by the browser. */
|
|
122
|
+
onAudioPlayback?: (state: AudioPlaybackState) => void;
|
|
113
123
|
};
|
|
114
124
|
export type BrowserVoiceSession = {
|
|
115
125
|
peerId: string;
|
|
@@ -153,6 +163,13 @@ export type BrowserVoiceSession = {
|
|
|
153
163
|
* success; false keeps the current (possibly synthetic) stream.
|
|
154
164
|
*/
|
|
155
165
|
requestAudioInputAccess: () => Promise<boolean>;
|
|
166
|
+
/** Inbound agent audio playback state (`idle` until first ontrack play attempt). */
|
|
167
|
+
getAudioPlaybackState: () => AudioPlaybackState;
|
|
168
|
+
/**
|
|
169
|
+
* Retry playback on the attached audio element (call from a user gesture when
|
|
170
|
+
* {@link getAudioPlaybackState} is `blocked`).
|
|
171
|
+
*/
|
|
172
|
+
unlockAudioPlayback: () => Promise<boolean>;
|
|
156
173
|
/**
|
|
157
174
|
* Resolves when the session meets the readiness profile (voice: PC + inbound/outbound
|
|
158
175
|
* audio tracks; data: PC + both data channels open) or rejects on timeout/failure.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-voice-session.d.ts","sourceRoot":"","sources":["../../src/browser/browser-voice-session.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAQL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,gCAAgC,CAAC;AAMxC,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-voice-session.d.ts","sourceRoot":"","sources":["../../src/browser/browser-voice-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ import { emitDiagnosticSafely, redactDiagnosticDetail, } from "./voice-session-d
|
|
|
9
9
|
import { waitForIceGatheringComplete } from "./wait-for-ice-gathering.js";
|
|
10
10
|
import { isWebRtcConnectRetryError, WebRtcConnectRetryError, } from "./webrtc-connect-retry.js";
|
|
11
11
|
import { acquireAudioInput, listAudioInputDevices as listBrowserAudioInputDevices, } from "./microphone.js";
|
|
12
|
+
import { createHiddenAudioElement, unlockAudioPlayback as unlockAudioPlaybackElement, } from "./audio-playback.js";
|
|
12
13
|
/** High-rate DC traffic logged at debug level — E2E stderr needs `LOAD_TEST_CLIENT_DEBUG=1`. */
|
|
13
14
|
const HIGH_FREQUENCY_DC_TYPES = new Set([
|
|
14
15
|
"keepalive",
|
|
@@ -138,6 +139,39 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
138
139
|
let audioInputState = "synthetic";
|
|
139
140
|
let audioInputDeviceId = null;
|
|
140
141
|
let disposeMicHandle = null;
|
|
142
|
+
const ownedAudioElement = options.requestMic !== false && !options.audioElement
|
|
143
|
+
? createHiddenAudioElement()
|
|
144
|
+
: null;
|
|
145
|
+
const playbackAudioElement = options.audioElement ?? ownedAudioElement;
|
|
146
|
+
let audioPlaybackState = "idle";
|
|
147
|
+
const disposeOwnedAudioElement = () => {
|
|
148
|
+
if (!ownedAudioElement)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
ownedAudioElement.pause();
|
|
152
|
+
ownedAudioElement.srcObject = null;
|
|
153
|
+
ownedAudioElement.remove();
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* ignore */
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const setAudioPlaybackState = (state) => {
|
|
160
|
+
audioPlaybackState = state;
|
|
161
|
+
options.onAudioPlayback?.(state);
|
|
162
|
+
};
|
|
163
|
+
const attemptInboundAudioPlayback = async () => {
|
|
164
|
+
if (!playbackAudioElement)
|
|
165
|
+
return;
|
|
166
|
+
const ok = await unlockAudioPlaybackElement(playbackAudioElement);
|
|
167
|
+
if (ok) {
|
|
168
|
+
setAudioPlaybackState("playing");
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
debug?.warn("webrtc", "audio_playback_blocked");
|
|
172
|
+
setAudioPlaybackState("blocked");
|
|
173
|
+
}
|
|
174
|
+
};
|
|
141
175
|
/** ICE candidates queued by negotiation generation until that PC is ready. */
|
|
142
176
|
const pendingIceByGeneration = new Map();
|
|
143
177
|
let connectionState = "new";
|
|
@@ -217,6 +251,7 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
217
251
|
let hasReachedReadyOnce = false;
|
|
218
252
|
let awaitingReconnectedCallback = false;
|
|
219
253
|
let lastReconnectAttemptForCallback = 0;
|
|
254
|
+
let lastReconnectReason;
|
|
220
255
|
const readinessProfile = resolveReadinessProfile({
|
|
221
256
|
requestMic: options.requestMic,
|
|
222
257
|
readiness: options.readiness,
|
|
@@ -312,8 +347,9 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
312
347
|
return;
|
|
313
348
|
pendingConnectFailure = null;
|
|
314
349
|
if (awaitingReconnectedCallback && hasReachedReadyOnce) {
|
|
315
|
-
options.onReconnected?.(lastReconnectAttemptForCallback);
|
|
350
|
+
options.onReconnected?.(lastReconnectAttemptForCallback, reconnectInfo());
|
|
316
351
|
awaitingReconnectedCallback = false;
|
|
352
|
+
lastReconnectReason = undefined;
|
|
317
353
|
}
|
|
318
354
|
hasReachedReadyOnce = true;
|
|
319
355
|
resolveConnected?.();
|
|
@@ -431,6 +467,10 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
431
467
|
return false;
|
|
432
468
|
return autoReconnectAttempts < maxAutoReconnectAttempts;
|
|
433
469
|
};
|
|
470
|
+
const reconnectInfo = (reason) => ({
|
|
471
|
+
reason: reason ?? lastReconnectReason ?? "unknown",
|
|
472
|
+
iceTransportPolicy: effectiveIceTransportPolicy,
|
|
473
|
+
});
|
|
434
474
|
const canIceRecover = () => {
|
|
435
475
|
if (gracefulDisconnect || reconnectPolicy === "new-session")
|
|
436
476
|
return false;
|
|
@@ -458,7 +498,8 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
458
498
|
if (effectiveIceTransportPolicy !== "relay") {
|
|
459
499
|
effectiveIceTransportPolicy = "relay";
|
|
460
500
|
}
|
|
461
|
-
|
|
501
|
+
lastReconnectReason = reason;
|
|
502
|
+
options.onIceRecovery?.(iceRecoveryAttempts, reconnectInfo(reason));
|
|
462
503
|
debug?.info("session", "ice_recovery_relay", `${reason} attempt=${iceRecoveryAttempts}`);
|
|
463
504
|
if (reconnectTimer)
|
|
464
505
|
clearTimeout(reconnectTimer);
|
|
@@ -835,9 +876,9 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
835
876
|
if (event.track.kind !== "audio")
|
|
836
877
|
return;
|
|
837
878
|
const stream = event.streams[0] ?? new MediaStream([event.track]);
|
|
838
|
-
if (
|
|
839
|
-
|
|
840
|
-
void
|
|
879
|
+
if (playbackAudioElement) {
|
|
880
|
+
playbackAudioElement.srcObject = stream;
|
|
881
|
+
void attemptInboundAudioPlayback();
|
|
841
882
|
}
|
|
842
883
|
options.onAgentAudioTrack?.(event.track);
|
|
843
884
|
updateConnectionSnapshot({ inboundAudioTrack: true });
|
|
@@ -1073,7 +1114,8 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
1073
1114
|
autoReconnectAttempts += 1;
|
|
1074
1115
|
lastReconnectAttemptForCallback = autoReconnectAttempts;
|
|
1075
1116
|
awaitingReconnectedCallback = true;
|
|
1076
|
-
|
|
1117
|
+
lastReconnectReason = reason;
|
|
1118
|
+
options.onReconnecting?.(autoReconnectAttempts, reconnectInfo(reason));
|
|
1077
1119
|
const delayMs = Math.min(1000 * 2 ** (autoReconnectAttempts - 1), 8000);
|
|
1078
1120
|
if (reconnectTimer)
|
|
1079
1121
|
clearTimeout(reconnectTimer);
|
|
@@ -1418,6 +1460,20 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
1418
1460
|
await switchAudioInput(deviceId);
|
|
1419
1461
|
},
|
|
1420
1462
|
requestAudioInputAccess: async () => switchAudioInput(audioInputDeviceId, { reRequest: true }),
|
|
1463
|
+
getAudioPlaybackState: () => audioPlaybackState,
|
|
1464
|
+
unlockAudioPlayback: async () => {
|
|
1465
|
+
if (!playbackAudioElement)
|
|
1466
|
+
return false;
|
|
1467
|
+
const ok = await unlockAudioPlaybackElement(playbackAudioElement);
|
|
1468
|
+
if (ok) {
|
|
1469
|
+
setAudioPlaybackState("playing");
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
debug?.warn("webrtc", "audio_playback_blocked");
|
|
1473
|
+
setAudioPlaybackState("blocked");
|
|
1474
|
+
}
|
|
1475
|
+
return ok;
|
|
1476
|
+
},
|
|
1421
1477
|
getConnectionState: () => connectionState,
|
|
1422
1478
|
getConnectionStatus: () => buildWebRtcConnectionStatus(connectionSnapshot, readinessProfile),
|
|
1423
1479
|
getWebRtcDiagnostics: async () => collectWebRtcDiagnostics(pc, buildWebRtcConnectionStatus(connectionSnapshot, readinessProfile)),
|
|
@@ -1426,6 +1482,7 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
1426
1482
|
autoReconnectAttempts = 0;
|
|
1427
1483
|
iceRecoveryAttempts = 0;
|
|
1428
1484
|
lastReconnectAttemptForCallback = 0;
|
|
1485
|
+
lastReconnectReason = "manual";
|
|
1429
1486
|
awaitingReconnectedCallback = true;
|
|
1430
1487
|
await reconnectSignaling();
|
|
1431
1488
|
},
|
|
@@ -1508,6 +1565,7 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
1508
1565
|
}
|
|
1509
1566
|
ws = null;
|
|
1510
1567
|
disposeCurrentMic();
|
|
1568
|
+
disposeOwnedAudioElement();
|
|
1511
1569
|
micRtpSender = null;
|
|
1512
1570
|
try {
|
|
1513
1571
|
localControl?.close();
|
|
@@ -1601,6 +1659,7 @@ export async function connectBrowserVoiceSession(options) {
|
|
|
1601
1659
|
pc = null;
|
|
1602
1660
|
ws = null;
|
|
1603
1661
|
disposeCurrentMic();
|
|
1662
|
+
disposeOwnedAudioElement();
|
|
1604
1663
|
micRtpSender = null;
|
|
1605
1664
|
try {
|
|
1606
1665
|
localControl?.close();
|