@absolutejs/voice 0.0.22-beta.654 → 0.0.22-beta.655
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/angular/index.js +30 -25
- package/dist/client/htmxBootstrap.js +30 -25
- package/dist/client/index.js +30 -25
- package/dist/embed/index.js +30 -25
- package/dist/embed/voice-widget.js +3 -3
- package/dist/react/index.js +30 -25
- package/dist/svelte/index.js +30 -25
- package/dist/testing/index.js +30 -25
- package/dist/vue/index.js +30 -25
- package/package.json +1 -1
package/dist/angular/index.js
CHANGED
|
@@ -687,6 +687,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
687
687
|
const emitConnection = (reconnect) => {
|
|
688
688
|
listeners.forEach((listener) => listener(reconnect));
|
|
689
689
|
};
|
|
690
|
+
const emitTerminalFailure = (message) => {
|
|
691
|
+
listeners.forEach((listener) => listener({
|
|
692
|
+
message,
|
|
693
|
+
recoverable: false,
|
|
694
|
+
type: "error"
|
|
695
|
+
}));
|
|
696
|
+
emitConnection({
|
|
697
|
+
reconnect: {
|
|
698
|
+
attempts: state.reconnectAttempts,
|
|
699
|
+
maxAttempts: maxReconnectAttempts,
|
|
700
|
+
status: "exhausted"
|
|
701
|
+
},
|
|
702
|
+
type: "connection"
|
|
703
|
+
});
|
|
704
|
+
};
|
|
690
705
|
const clearTimers = () => {
|
|
691
706
|
if (state.pingInterval) {
|
|
692
707
|
clearInterval(state.pingInterval);
|
|
@@ -735,14 +750,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
735
750
|
});
|
|
736
751
|
state.reconnectTimeout = setTimeout(async () => {
|
|
737
752
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
738
|
-
|
|
739
|
-
reconnect: {
|
|
740
|
-
attempts: state.reconnectAttempts,
|
|
741
|
-
maxAttempts: maxReconnectAttempts,
|
|
742
|
-
status: "exhausted"
|
|
743
|
-
},
|
|
744
|
-
type: "connection"
|
|
745
|
-
});
|
|
753
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
746
754
|
return;
|
|
747
755
|
}
|
|
748
756
|
try {
|
|
@@ -756,14 +764,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
756
764
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
757
765
|
scheduleReconnect();
|
|
758
766
|
} else {
|
|
759
|
-
|
|
760
|
-
reconnect: {
|
|
761
|
-
attempts: state.reconnectAttempts,
|
|
762
|
-
maxAttempts: maxReconnectAttempts,
|
|
763
|
-
status: "exhausted"
|
|
764
|
-
},
|
|
765
|
-
type: "connection"
|
|
766
|
-
});
|
|
767
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
767
768
|
}
|
|
768
769
|
return;
|
|
769
770
|
}
|
|
@@ -853,15 +854,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
853
854
|
if (reconnectable) {
|
|
854
855
|
scheduleReconnect();
|
|
855
856
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
857
|
+
if (authorizationFailure) {
|
|
858
|
+
emitConnection({
|
|
859
|
+
reconnect: {
|
|
860
|
+
attempts: state.reconnectAttempts,
|
|
861
|
+
lastDisconnectAt: Date.now(),
|
|
862
|
+
maxAttempts: maxReconnectAttempts,
|
|
863
|
+
status: "exhausted"
|
|
864
|
+
},
|
|
865
|
+
type: "connection"
|
|
866
|
+
});
|
|
867
|
+
} else {
|
|
868
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
869
|
+
}
|
|
865
870
|
}
|
|
866
871
|
};
|
|
867
872
|
state.ws = ws;
|
|
@@ -604,6 +604,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
604
604
|
const emitConnection = (reconnect) => {
|
|
605
605
|
listeners.forEach((listener) => listener(reconnect));
|
|
606
606
|
};
|
|
607
|
+
const emitTerminalFailure = (message) => {
|
|
608
|
+
listeners.forEach((listener) => listener({
|
|
609
|
+
message,
|
|
610
|
+
recoverable: false,
|
|
611
|
+
type: "error"
|
|
612
|
+
}));
|
|
613
|
+
emitConnection({
|
|
614
|
+
reconnect: {
|
|
615
|
+
attempts: state.reconnectAttempts,
|
|
616
|
+
maxAttempts: maxReconnectAttempts,
|
|
617
|
+
status: "exhausted"
|
|
618
|
+
},
|
|
619
|
+
type: "connection"
|
|
620
|
+
});
|
|
621
|
+
};
|
|
607
622
|
const clearTimers = () => {
|
|
608
623
|
if (state.pingInterval) {
|
|
609
624
|
clearInterval(state.pingInterval);
|
|
@@ -652,14 +667,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
652
667
|
});
|
|
653
668
|
state.reconnectTimeout = setTimeout(async () => {
|
|
654
669
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
655
|
-
|
|
656
|
-
reconnect: {
|
|
657
|
-
attempts: state.reconnectAttempts,
|
|
658
|
-
maxAttempts: maxReconnectAttempts,
|
|
659
|
-
status: "exhausted"
|
|
660
|
-
},
|
|
661
|
-
type: "connection"
|
|
662
|
-
});
|
|
670
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
663
671
|
return;
|
|
664
672
|
}
|
|
665
673
|
try {
|
|
@@ -673,14 +681,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
673
681
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
674
682
|
scheduleReconnect();
|
|
675
683
|
} else {
|
|
676
|
-
|
|
677
|
-
reconnect: {
|
|
678
|
-
attempts: state.reconnectAttempts,
|
|
679
|
-
maxAttempts: maxReconnectAttempts,
|
|
680
|
-
status: "exhausted"
|
|
681
|
-
},
|
|
682
|
-
type: "connection"
|
|
683
|
-
});
|
|
684
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
684
685
|
}
|
|
685
686
|
return;
|
|
686
687
|
}
|
|
@@ -770,15 +771,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
770
771
|
if (reconnectable) {
|
|
771
772
|
scheduleReconnect();
|
|
772
773
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
774
|
+
if (authorizationFailure) {
|
|
775
|
+
emitConnection({
|
|
776
|
+
reconnect: {
|
|
777
|
+
attempts: state.reconnectAttempts,
|
|
778
|
+
lastDisconnectAt: Date.now(),
|
|
779
|
+
maxAttempts: maxReconnectAttempts,
|
|
780
|
+
status: "exhausted"
|
|
781
|
+
},
|
|
782
|
+
type: "connection"
|
|
783
|
+
});
|
|
784
|
+
} else {
|
|
785
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
786
|
+
}
|
|
782
787
|
}
|
|
783
788
|
};
|
|
784
789
|
state.ws = ws;
|
package/dist/client/index.js
CHANGED
|
@@ -209,6 +209,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
209
209
|
const emitConnection = (reconnect) => {
|
|
210
210
|
listeners.forEach((listener) => listener(reconnect));
|
|
211
211
|
};
|
|
212
|
+
const emitTerminalFailure = (message) => {
|
|
213
|
+
listeners.forEach((listener) => listener({
|
|
214
|
+
message,
|
|
215
|
+
recoverable: false,
|
|
216
|
+
type: "error"
|
|
217
|
+
}));
|
|
218
|
+
emitConnection({
|
|
219
|
+
reconnect: {
|
|
220
|
+
attempts: state.reconnectAttempts,
|
|
221
|
+
maxAttempts: maxReconnectAttempts,
|
|
222
|
+
status: "exhausted"
|
|
223
|
+
},
|
|
224
|
+
type: "connection"
|
|
225
|
+
});
|
|
226
|
+
};
|
|
212
227
|
const clearTimers = () => {
|
|
213
228
|
if (state.pingInterval) {
|
|
214
229
|
clearInterval(state.pingInterval);
|
|
@@ -257,14 +272,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
257
272
|
});
|
|
258
273
|
state.reconnectTimeout = setTimeout(async () => {
|
|
259
274
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
260
|
-
|
|
261
|
-
reconnect: {
|
|
262
|
-
attempts: state.reconnectAttempts,
|
|
263
|
-
maxAttempts: maxReconnectAttempts,
|
|
264
|
-
status: "exhausted"
|
|
265
|
-
},
|
|
266
|
-
type: "connection"
|
|
267
|
-
});
|
|
275
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
268
276
|
return;
|
|
269
277
|
}
|
|
270
278
|
try {
|
|
@@ -278,14 +286,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
278
286
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
279
287
|
scheduleReconnect();
|
|
280
288
|
} else {
|
|
281
|
-
|
|
282
|
-
reconnect: {
|
|
283
|
-
attempts: state.reconnectAttempts,
|
|
284
|
-
maxAttempts: maxReconnectAttempts,
|
|
285
|
-
status: "exhausted"
|
|
286
|
-
},
|
|
287
|
-
type: "connection"
|
|
288
|
-
});
|
|
289
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
289
290
|
}
|
|
290
291
|
return;
|
|
291
292
|
}
|
|
@@ -375,15 +376,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
375
376
|
if (reconnectable) {
|
|
376
377
|
scheduleReconnect();
|
|
377
378
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
379
|
+
if (authorizationFailure) {
|
|
380
|
+
emitConnection({
|
|
381
|
+
reconnect: {
|
|
382
|
+
attempts: state.reconnectAttempts,
|
|
383
|
+
lastDisconnectAt: Date.now(),
|
|
384
|
+
maxAttempts: maxReconnectAttempts,
|
|
385
|
+
status: "exhausted"
|
|
386
|
+
},
|
|
387
|
+
type: "connection"
|
|
388
|
+
});
|
|
389
|
+
} else {
|
|
390
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
391
|
+
}
|
|
387
392
|
}
|
|
388
393
|
};
|
|
389
394
|
state.ws = ws;
|
package/dist/embed/index.js
CHANGED
|
@@ -601,6 +601,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
601
601
|
const emitConnection = (reconnect) => {
|
|
602
602
|
listeners.forEach((listener) => listener(reconnect));
|
|
603
603
|
};
|
|
604
|
+
const emitTerminalFailure = (message) => {
|
|
605
|
+
listeners.forEach((listener) => listener({
|
|
606
|
+
message,
|
|
607
|
+
recoverable: false,
|
|
608
|
+
type: "error"
|
|
609
|
+
}));
|
|
610
|
+
emitConnection({
|
|
611
|
+
reconnect: {
|
|
612
|
+
attempts: state.reconnectAttempts,
|
|
613
|
+
maxAttempts: maxReconnectAttempts,
|
|
614
|
+
status: "exhausted"
|
|
615
|
+
},
|
|
616
|
+
type: "connection"
|
|
617
|
+
});
|
|
618
|
+
};
|
|
604
619
|
const clearTimers = () => {
|
|
605
620
|
if (state.pingInterval) {
|
|
606
621
|
clearInterval(state.pingInterval);
|
|
@@ -649,14 +664,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
649
664
|
});
|
|
650
665
|
state.reconnectTimeout = setTimeout(async () => {
|
|
651
666
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
652
|
-
|
|
653
|
-
reconnect: {
|
|
654
|
-
attempts: state.reconnectAttempts,
|
|
655
|
-
maxAttempts: maxReconnectAttempts,
|
|
656
|
-
status: "exhausted"
|
|
657
|
-
},
|
|
658
|
-
type: "connection"
|
|
659
|
-
});
|
|
667
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
660
668
|
return;
|
|
661
669
|
}
|
|
662
670
|
try {
|
|
@@ -670,14 +678,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
670
678
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
671
679
|
scheduleReconnect();
|
|
672
680
|
} else {
|
|
673
|
-
|
|
674
|
-
reconnect: {
|
|
675
|
-
attempts: state.reconnectAttempts,
|
|
676
|
-
maxAttempts: maxReconnectAttempts,
|
|
677
|
-
status: "exhausted"
|
|
678
|
-
},
|
|
679
|
-
type: "connection"
|
|
680
|
-
});
|
|
681
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
681
682
|
}
|
|
682
683
|
return;
|
|
683
684
|
}
|
|
@@ -767,15 +768,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
767
768
|
if (reconnectable) {
|
|
768
769
|
scheduleReconnect();
|
|
769
770
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
771
|
+
if (authorizationFailure) {
|
|
772
|
+
emitConnection({
|
|
773
|
+
reconnect: {
|
|
774
|
+
attempts: state.reconnectAttempts,
|
|
775
|
+
lastDisconnectAt: Date.now(),
|
|
776
|
+
maxAttempts: maxReconnectAttempts,
|
|
777
|
+
status: "exhausted"
|
|
778
|
+
},
|
|
779
|
+
type: "connection"
|
|
780
|
+
});
|
|
781
|
+
} else {
|
|
782
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
783
|
+
}
|
|
779
784
|
}
|
|
780
785
|
};
|
|
781
786
|
state.ws = ws;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(()=>{var{defineProperty:x,getOwnPropertyNames:U0,getOwnPropertyDescriptor:L0}=Object,G0=Object.prototype.hasOwnProperty;function W0(g){return this[g]}var D0=(g)=>{var A=(f??=new WeakMap).get(g),C;if(A)return A;if(A=x({},"__esModule",{value:!0}),g&&typeof g==="object"||typeof g==="function"){for(var V of U0(g))if(!G0.call(A,V))x(A,V,{get:W0.bind(g,V),enumerable:!(C=L0(g,V))||C.enumerable})}return f.set(g,A),A},f;var S0=(g)=>g;function y0(g,A){this[g]=S0.bind(null,A)}var X0=(g,A)=>{for(var C in A)x(g,C,{get:A[C],enumerable:!0,configurable:!0,set:y0.bind(A,C)})};var t0={};X0(t0,{mount:()=>T0,default:()=>e0,VOICE_EMBED_VERSION:()=>_0});var O0=(g)=>{if(typeof g!=="string")return g;return document.querySelector(g)},h0=(g,A,C,V)=>{let c=A??g.getAttribute("hx-get")??"";if(!c)return"";let T=new URL(c,window.location.origin);if(V)T.searchParams.set(C,V);else T.searchParams.delete(C);return`${T.pathname}${T.search}${T.hash}`},d=(g,A)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let C=O0(A.element);if(!C)return()=>{};let V=A.eventName??"voice-refresh",c=A.sessionQueryParam??"sessionId",T=()=>{let I=window,G=h0(C,A.route,c,g.sessionId);if(G)C.setAttribute("hx-get",G);I.htmx?.process?.(C),I.htmx?.trigger?.(C,V)},U=g.subscribe(T);return T(),()=>{U()}};var J0=(g)=>Math.max(-1,Math.min(1,g)),Y0=(g)=>{let A=new Int16Array(g.length);for(let C=0;C<g.length;C+=1){let V=J0(g[C]??0);A[C]=V<0?V*32768:V*32767}return new Uint8Array(A.buffer)},Z0=(g)=>{let A=g instanceof Uint8Array?g:new Uint8Array(g);if(A.byteLength<2)return 0;let C=new Int16Array(A.buffer,A.byteOffset,Math.floor(A.byteLength/2));if(C.length===0)return 0;let V=0;for(let c of C){let T=c/32768;V+=T*T}return Math.min(1,Math.max(0,Math.sqrt(V/C.length)*5.5))},w0=(g,A,C)=>{if(A===C)return g;let V=A/C,c=Math.round(g.length/V),T=new Float32Array(c),U=0,I=0;while(U<T.length){let G=Math.round((U+1)*V),W=0,_=0;for(let L=I;L<G&&L<g.length;L+=1)W+=g[L]??0,_+=1;T[U]=_>0?W/_:0,U+=1,I=G}return T},l=(g)=>{let A=null,C=null,V=null,c=null,T=async()=>{if(!g.stream&&(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia))throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let I=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!I)throw Error("Browser microphone capture requires AudioContext support.");try{if(c=g.stream??await navigator.mediaDevices.getUserMedia({audio:{autoGainControl:!0,channelCount:g.channelCount??1,echoCancellation:!0,noiseSuppression:!0}}),A=new I,A.state==="suspended")await A.resume();C=A.createMediaStreamSource(c),V=A.createScriptProcessor(4096,1,1),V.onaudioprocess=(G)=>{let W=G.inputBuffer.getChannelData(0),_=w0(W,A?.sampleRate??48000,g.sampleRateHz??16000),L=Y0(_);g.onLevel?.(Z0(L)),g.onAudio(L)},C.connect(V),V.connect(A.destination)}catch(G){throw U(),G}},U=()=>{V?.disconnect(),C?.disconnect(),c?.getTracks().forEach((I)=>I.stop()),A?.close(),g.onLevel?.(0),A=null,c=null,V=null,C=null};return{start:T,stop:U}};var k=(g)=>{if(typeof g==="string"&&g.trim())return g;if(g instanceof Error&&g.message.trim())return g.message;if(g&&typeof g==="object"){let A=g;for(let C of["message","reason","description"]){let V=A[C];if(typeof V==="string"&&V.trim())return V}if("error"in A)return k(A.error);if("cause"in A)return k(A.cause);try{return JSON.stringify(g)}catch{}}return"Unexpected error"},v=(g)=>{switch(g.type){case"audio":return{chunk:Uint8Array.from(atob(g.chunkBase64),(A)=>A.charCodeAt(0)),format:g.format,receivedAt:g.receivedAt,turnId:g.turnId,type:"audio"};case"assistant":return{text:g.text,turnId:g.turnId,type:"assistant"};case"assistant_delta":return{delta:g.delta,turnId:g.turnId,type:"assistant_delta"};case"complete":return{sessionId:g.sessionId,type:"complete"};case"connection":return{reconnect:g.reconnect,type:"connection"};case"call_lifecycle":return{event:g.event,sessionId:g.sessionId,type:"call_lifecycle"};case"error":return{message:k(g.message),recoverable:g.recoverable,type:"error"};case"call_control_ack":return null;case"final":return{transcript:g.transcript,type:"final"};case"partial":return{transcript:g.transcript,type:"partial"};case"replay":return{assistantTexts:g.assistantTexts,call:g.call,partial:g.partial,scenarioId:g.scenarioId,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,status:g.status,turns:g.turns,type:"replay"};case"session":return{sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,type:"session"};case"turn":return{turn:g.turn,type:"turn"};default:return null}};var Tg=Math.PI*2;var P=(g,A,C,V)=>{g.push({code:C,message:V,severity:A})};var Q0=(g)=>g.length===0?void 0:g.reduce((A,C)=>A+C,0)/g.length,M=(g)=>g.length===0?void 0:Math.max(...g);var X=(g,A)=>{let C=g[A];return typeof C==="number"&&Number.isFinite(C)?C:void 0},B=(g,A)=>{let C=g[A];return typeof C==="boolean"?C:void 0},J=(g,A)=>{let C=g[A];return typeof C==="string"?C:void 0},F=(g)=>String(g.id??J(g,"ssrc")??X(g,"ssrc")??J(g,"trackIdentifier")??J(g,"mid")??"unknown"),i=(g)=>g===void 0?void 0:g*1000;var P0=(g)=>{let A={};for(let[C,V]of Object.entries(g))if(V===null||typeof V==="boolean"||typeof V==="number"||typeof V==="string")A[C]=V;return A};var n=(g={})=>{let A=g.stats??[],C=[],V=A.filter((R)=>R.type==="inbound-rtp"&&J(R,"kind")!=="video"),c=A.filter((R)=>R.type==="outbound-rtp"&&J(R,"kind")!=="video"),T=A.filter((R)=>R.type==="candidate-pair"),U=A.filter((R)=>(R.type==="track"||R.type==="media-source")&&J(R,"kind")==="audio"),I=T.filter((R)=>B(R,"selected")===!0||B(R,"nominated")===!0||J(R,"state")==="succeeded").length,G=U.filter((R)=>J(R,"readyState")!=="ended"&&J(R,"trackState")!=="ended"&&B(R,"ended")!==!0).length,W=U.filter((R)=>J(R,"readyState")==="ended"||J(R,"trackState")==="ended"||B(R,"ended")===!0).length,_=V.reduce((R,O)=>R+(X(O,"packetsReceived")??0),0),L=c.reduce((R,O)=>R+(X(O,"packetsSent")??0),0),$=[...V,...c].reduce((R,O)=>R+Math.max(0,X(O,"packetsLost")??0),0),E=_+$,w=E===0?0:$/E,D=V.reduce((R,O)=>R+(X(O,"bytesReceived")??0),0),Y=c.reduce((R,O)=>R+(X(O,"bytesSent")??0),0),Z=M(T.map((R)=>i(X(R,"currentRoundTripTime")??X(R,"roundTripTime"))).filter((R)=>R!==void 0)),h=M([...V,...c].map((R)=>i(X(R,"jitter"))).filter((R)=>R!==void 0)),z=M(V.map((R)=>{let O=X(R,"jitterBufferDelay"),b=X(R,"jitterBufferEmittedCount");return O!==void 0&&b!==void 0&&b>0?O/b*1000:void 0}).filter((R)=>R!==void 0)),q=U.map((R)=>X(R,"audioLevel")).filter((R)=>R!==void 0);if(g.requireConnectedCandidatePair&&T.length>0&&I===0)P(C,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(g.requireLiveAudioTrack&&G===0)P(C,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(g.maxPacketLossRatio!==void 0&&w>g.maxPacketLossRatio)P(C,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(w)} above ${String(g.maxPacketLossRatio)}.`);if(g.maxRoundTripTimeMs!==void 0&&Z!==void 0&&Z>g.maxRoundTripTimeMs)P(C,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(Z)}ms above ${String(g.maxRoundTripTimeMs)}ms.`);if(g.maxJitterMs!==void 0&&h!==void 0&&h>g.maxJitterMs)P(C,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(h)}ms above ${String(g.maxJitterMs)}ms.`);return{activeCandidatePairs:I,audioLevelAverage:Q0(q),bytesReceived:D,bytesSent:Y,checkedAt:Date.now(),endedAudioTracks:W,inboundPackets:_,issues:C,jitterBufferDelayMs:z,jitterMs:h,liveAudioTracks:G,outboundPackets:L,packetLossRatio:w,packetsLost:$,roundTripTimeMs:Z,status:C.some((R)=>R.severity==="error")?"fail":C.length>0?"warn":"pass",totalStats:A.length}},o=async(g)=>{return[...(await g.peerConnection.getStats(g.selector??null)).values()].map(P0)};var m=(g={})=>{let A=g.stats??[],C=g.previousStats??[],V=[],c=new Map(C.map(($)=>[F($),$])),U=A.filter(($)=>($.type==="inbound-rtp"||$.type==="outbound-rtp")&&J($,"kind")!=="video"&&J($,"mediaType")!=="video").map(($)=>{let E=$.type==="outbound-rtp"?"outbound":"inbound",w=E==="outbound"?"packetsSent":"packetsReceived",D=E==="outbound"?"bytesSent":"bytesReceived",Y=c.get(F($)),Z=X($,w),h=Y?X(Y,w):void 0,z=X($,D),q=Y?X(Y,D):void 0,R=$.timestamp!==void 0&&Y?.timestamp!==void 0?$.timestamp-Y.timestamp:void 0;return{bytesDelta:z!==void 0&&q!==void 0?z-q:void 0,currentPackets:Z,direction:E,id:F($),packetDelta:Z!==void 0&&h!==void 0?Z-h:void 0,previousPackets:h,timeDeltaMs:R}}),I=U.filter(($)=>$.direction==="inbound"),G=U.filter(($)=>$.direction==="outbound"),W=M(U.map(($)=>$.timeDeltaMs).filter(($)=>$!==void 0)),_=I.filter(($)=>g.maxInboundPacketStallMs!==void 0&&$.timeDeltaMs!==void 0&&$.timeDeltaMs>=g.maxInboundPacketStallMs&&$.packetDelta!==void 0&&$.packetDelta<=0).length,L=G.filter(($)=>g.maxOutboundPacketStallMs!==void 0&&$.timeDeltaMs!==void 0&&$.timeDeltaMs>=g.maxOutboundPacketStallMs&&$.packetDelta!==void 0&&$.packetDelta<=0).length;if(g.requireInboundAudio&&I.length===0)P(V,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(g.requireOutboundAudio&&G.length===0)P(V,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(g.maxGapMs!==void 0&&W!==void 0&&W>g.maxGapMs)P(V,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(W)}ms above ${String(g.maxGapMs)}ms.`);if(_>0)P(V,"error","media.webrtc_inbound_stalled",`${String(_)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(L>0)P(V,"error","media.webrtc_outbound_stalled",`${String(L)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:I.length,issues:V,maxObservedGapMs:W,outboundAudioStreams:G.length,stalledInboundStreams:_,stalledOutboundStreams:L,status:V.some(($)=>$.severity==="error")?"fail":V.length>0?"warn":"pass",streams:U,totalStats:A.length}};var K0="/api/voice/browser-media",E0=5000,N0=async(g)=>g.peerConnection??await g.getPeerConnection?.()??null,z0=async(g,A)=>{let C=A.fetch??globalThis.fetch;if(!C)return;await C(A.path??K0,{body:JSON.stringify(g),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},r=(g)=>{let A=null,C=[],V=async()=>{let U=await N0(g);if(!U)return;let I=await o({peerConnection:U}),G=n({...g,stats:I}),W=g.continuity===!1?void 0:m({...g.continuity,previousStats:C,stats:I}),_={at:Date.now(),continuity:W,report:G,scenarioId:g.getScenarioId?.()??null,sessionId:g.getSessionId?.()??null};return C=I,g.onReport?.(_),await z0(_,g),_},c=()=>{V().catch((U)=>{g.onError?.(U)})},T=()=>{if(A)clearInterval(A),A=null};return{close:T,reportOnce:V,stop:T,start:()=>{if(A)return;c(),A=setInterval(c,g.intervalMs??E0)}}};var q0=(g,A,C)=>Math.min(C,A*2**(Math.max(1,g)-1));var N=()=>{},b0=()=>Promise.resolve(),B0=()=>N,M0={callControl:b0,close:N,disconnect:N,endTurn:N,send:N,sendAudio:N,simulateDisconnect:N,subscribe:B0,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",start:()=>{}},j0=()=>crypto.randomUUID(),x0=(g,A,C,V)=>{let{hostname:c,port:T,protocol:U}=window.location,I=U==="https:"?"wss:":"ws:",G=T?`:${T}`:"",W=new URL(`${I}//${c}${G}${g}`);if(W.searchParams.set("sessionId",A),C)W.searchParams.set("scenarioId",C);for(let[_,L]of Object.entries(V))if(_!=="sessionId"&&_!=="scenarioId"&&L)W.searchParams.set(_,L);return W.toString()},k0=(g)=>{if(!g||typeof g!=="object"||!("type"in g))return!1;switch(g.type){case"audio":case"assistant":case"call_lifecycle":case"call_control_ack":case"complete":case"connection":case"error":case"final":case"partial":case"pong":case"replay":case"session":case"turn":return!0;default:return!1}},F0=(g)=>{if(typeof g.data!=="string")return null;try{let A=JSON.parse(g.data);return k0(A)?A:null}catch{return null}},u=(g,A={})=>{if(typeof window>"u")return M0;let C=new Set,V=new Map,c=A.reconnect!==!1,T=A.maxReconnectAttempts??15,U=A.reconnectMaxDelayMs??8000,I=A.pingInterval??30000,G=A.reconnectResetAfterMs??30000,W=(H)=>q0(H,500,U),_={isConnected:!1,pendingMessages:[],scenarioId:A.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectResetTimeout:null,reconnectTimeout:null,sessionId:A.sessionId??j0(),ws:null},L=(H)=>{C.forEach((S)=>S(H))},$=()=>{if(_.pingInterval)clearInterval(_.pingInterval),_.pingInterval=null;if(_.reconnectTimeout)clearTimeout(_.reconnectTimeout),_.reconnectTimeout=null;if(_.reconnectResetTimeout)clearTimeout(_.reconnectResetTimeout),_.reconnectResetTimeout=null},E=()=>{if(_.ws?.readyState!==1)return;while(_.pendingMessages.length>0){let H=_.pendingMessages.shift();if(H!==void 0)_.ws.send(H)}},w=(H)=>{for(let S of V.values())clearTimeout(S.timeout),S.reject(Error(H));V.clear()},D=()=>{_.reconnectAttempts+=1;let H=W(_.reconnectAttempts),S=Date.now()+H;L({reconnect:{attempts:_.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:T,nextAttemptAt:S,status:"reconnecting"},type:"connection"}),_.reconnectTimeout=setTimeout(async()=>{if(_.reconnectAttempts>T){L({reconnect:{attempts:_.reconnectAttempts,maxAttempts:T,status:"exhausted"},type:"connection"});return}try{await A.prepareReconnect?.({attempt:_.reconnectAttempts,path:g,scenarioId:_.scenarioId,sessionId:_.sessionId})}catch{if(_.reconnectAttempts<T)D();else L({reconnect:{attempts:_.reconnectAttempts,maxAttempts:T,status:"exhausted"},type:"connection"});return}Y()},H)},Y=()=>{let H=new WebSocket(x0(g,_.sessionId,_.scenarioId,A.query??{}));H.binaryType="arraybuffer",H.onopen=()=>{if(_.ws!==H){H.close(1000);return}let S=_.reconnectAttempts>0;if(_.isConnected=!0,E(),S)L({reconnect:{attempts:_.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:T,status:"resumed"},type:"connection"}),_.reconnectResetTimeout=setTimeout(()=>{if(_.ws===H&&H.readyState===1)_.reconnectAttempts=0;_.reconnectResetTimeout=null},G);C.forEach((y)=>y({scenarioId:_.scenarioId??void 0,sessionId:_.sessionId,status:"active",type:"session"})),_.pingInterval=setInterval(()=>{if(H.readyState===1)H.send(JSON.stringify({type:"ping"}))},I)},H.onmessage=(S)=>{if(_.ws!==H)return;let y=F0(S);if(!y)return;if(y.type==="session")_.sessionId=y.sessionId,_.scenarioId=y.scenarioId??_.scenarioId;if(y.type==="call_control_ack"){let Q=V.get(y.requestId);if(Q)if(clearTimeout(Q.timeout),V.delete(y.requestId),y.ok)Q.resolve();else Q.reject(Error(y.message??`${y.action} was not applied`))}C.forEach((Q)=>Q(y))},H.onclose=(S)=>{if(_.ws!==H)return;_.ws=null,_.isConnected=!1,$();let y=c&&S.code!==1000&&S.code!==4401&&S.code!==4403&&_.reconnectAttempts<T;if(S.code===4401||S.code===4403)C.forEach((j)=>j({message:S.code===4401?"Voice authorization expired or was rejected.":"Voice authorization was forbidden.",recoverable:!1,type:"error"}));if(y)D();else if(c&&S.code!==1000)L({reconnect:{attempts:_.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:T,status:"exhausted"},type:"connection"})},_.ws=H},Z=(H)=>{if(_.ws?.readyState===1){_.ws.send(H);return}if(typeof H!=="string")return;if(_.pendingMessages.length>=100)_.pendingMessages.shift();_.pendingMessages.push(H)},h=(H)=>{Z(JSON.stringify(H))},z=(H={})=>{if(H.sessionId)_.sessionId=H.sessionId;if(H.scenarioId)_.scenarioId=H.scenarioId;h({scenarioId:_.scenarioId??void 0,sessionId:_.sessionId,type:"start"})},q=(H)=>{Z(H)},R=()=>{h({type:"end_turn"})},O=(H)=>{let S=crypto.randomUUID(),{promise:y,reject:Q,resolve:j}=Promise.withResolvers(),I0=setTimeout(()=>{V.delete(S),Q(Error(`${H.action} acknowledgement timed out`))},5000);return V.set(S,{reject:Q,resolve:j,timeout:I0}),h({...H,requestId:S,type:"call_control"}),y},b=(H="client-close")=>{if($(),w("Voice connection closed"),_.ws){let S=_.ws;if(_.ws=null,S.readyState===1)S.send(JSON.stringify({reason:H,type:"close"}));S.close(1000)}_.isConnected=!1,C.clear()},R0=()=>{if($(),w("Voice connection disconnected"),_.ws){let H=_.ws;_.ws=null,H.close(1000)}_.isConnected=!1,C.clear()},$0=()=>{if(_.ws?.readyState===1)_.ws.close(4000,"absolutejs-voice-reconnect-proof")},H0=(H)=>{return C.add(H),()=>{C.delete(H)}};return Y(),{callControl:O,close:b,disconnect:R0,endTurn:R,send:h,sendAudio:q,simulateDisconnect:$0,start:z,subscribe:H0,getReadyState:()=>_.ws?.readyState??3,getScenarioId:()=>_.scenarioId??"",getSessionId:()=>_.sessionId}};var f0=()=>({attempts:0,maxAttempts:0,status:"idle"}),d0=(g,A)=>{let C=A.trim().replace(/\s+/g," ");if(!C)return g;if(!g)return C;if(g===C||g.endsWith(C))return g;if(C.includes(g))return C;return`${g} ${C}`},l0=(g,A)=>{let C=A.trim().replace(/\s+/g," ");if(!g)return C;if(!C||g.endsWith(C))return g;return`${g} ${C}`},v0=()=>({assistantAudio:[],assistantStreamingText:"",assistantTexts:[],call:null,error:null,isConnected:!1,partial:"",reconnect:f0(),scenarioId:null,sessionId:null,sessionMetadata:null,status:"idle",turns:[]}),s=()=>{let g=v0(),A="",C=new Set,V=()=>{C.forEach((T)=>T())};return{dispatch:(T)=>{switch(T.type){case"audio":g={...g,assistantAudio:[...g.assistantAudio,{chunk:T.chunk,format:T.format,receivedAt:T.receivedAt,turnId:T.turnId}]};break;case"assistant":g={...g,assistantStreamingText:"",assistantTexts:[...g.assistantTexts,T.text]};break;case"assistant_delta":g={...g,assistantStreamingText:`${g.assistantStreamingText}${T.delta}`};break;case"complete":g={...g,sessionId:T.sessionId,status:"completed"};break;case"call_lifecycle":g={...g,call:{...g.call,disposition:T.event.type==="end"?T.event.disposition:g.call?.disposition,endedAt:T.event.type==="end"?T.event.at:g.call?.endedAt,events:[...g.call?.events??[],T.event],lastEventAt:T.event.at,startedAt:g.call?.startedAt??T.event.at},sessionId:T.sessionId};break;case"connected":g={...g,isConnected:!0,reconnect:g.reconnect.status==="reconnecting"?{...g.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:g.reconnect};break;case"connection":g={...g,reconnect:T.reconnect};break;case"disconnected":g={...g,isConnected:!1};break;case"error":g={...g,error:T.message,...T.recoverable===!1?{isConnected:!1,status:"failed"}:{}};break;case"final":A=d0(A,T.transcript.text),g={...g,partial:A};break;case"partial":g={...g,partial:l0(A,T.transcript.text)};break;case"replay":A=T.partial,g={...g,assistantStreamingText:"",assistantTexts:[...T.assistantTexts],call:T.call??null,error:null,isConnected:T.status==="active",partial:T.partial,reconnect:g.reconnect.status==="reconnecting"?{...g.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:g.reconnect,scenarioId:T.scenarioId??g.scenarioId,sessionId:T.sessionId,sessionMetadata:T.sessionMetadata??g.sessionMetadata,status:T.status,turns:[...T.turns]};break;case"session":g={...g,error:null,scenarioId:T.scenarioId??g.scenarioId,isConnected:T.status==="active",sessionId:T.sessionId,sessionMetadata:T.sessionMetadata??g.sessionMetadata,status:T.status};break;case"turn":A="",g={...g,partial:"",turns:[...g.turns,T.turn]};break}V()},getServerSnapshot:()=>g,getSnapshot:()=>g,subscribe:(T)=>{return C.add(T),()=>{C.delete(T)}}}};var a=(g,A={})=>{let C=u(g,A),V=s(),c=A.browserMedia&&typeof window<"u"?r({...A.browserMedia,getScenarioId:()=>A.browserMedia?A.browserMedia.getScenarioId?.()??C.getScenarioId():C.getScenarioId(),getSessionId:()=>A.browserMedia?A.browserMedia.getSessionId?.()??C.getSessionId():C.getSessionId()}):null,T=new Set,U=(_)=>Promise.resolve().then(()=>{if(!_?.sessionId&&!_?.scenarioId)return;C.start(_),c?.start()}),I=()=>{T.forEach((_)=>_())},G=()=>{if(!A.reconnectReportPath||typeof fetch>"u")return;let _=V.getSnapshot(),L=JSON.stringify({at:Date.now(),reconnect:_.reconnect,scenarioId:_.scenarioId,sessionId:C.getSessionId(),turnIds:_.turns.map(($)=>$.id)});fetch(A.reconnectReportPath,{body:L,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},W=C.subscribe((_)=>{let L=v(_);if(L){if(V.dispatch(L),_.type==="connection")G();I()}});return{start:U,get assistantAudio(){return V.getSnapshot().assistantAudio},get assistantTexts(){return V.getSnapshot().assistantTexts},get assistantStreamingText(){return V.getSnapshot().assistantStreamingText},get call(){return V.getSnapshot().call},callControl(_){return C.callControl(_)},close(_){W(),c?.close(),C.close(_),V.dispatch({type:"disconnected"}),I()},disconnect(){W(),c?.close(),C.disconnect(),V.dispatch({type:"disconnected"}),I()},endTurn(){C.endTurn()},get error(){return V.getSnapshot().error},getServerSnapshot(){return V.getServerSnapshot()},getSnapshot(){return V.getSnapshot()},get isConnected(){return V.getSnapshot().isConnected},get partial(){return V.getSnapshot().partial},get reconnect(){return V.getSnapshot().reconnect},get scenarioId(){return V.getSnapshot().scenarioId},sendAudio(_){C.sendAudio(_)},get sessionId(){return C.getSessionId()},get sessionMetadata(){return V.getSnapshot().sessionMetadata},simulateDisconnect(){C.simulateDisconnect()},get status(){return V.getSnapshot().status},subscribe(_){return T.add(_),()=>{T.delete(_)}},get turns(){return V.getSnapshot().turns}}};var p=(g)=>{if(!g||g.enabled===!1)return;return{enabled:!0,maxGain:g.maxGain??3,noiseGateAttenuation:g.noiseGateAttenuation??0.15,noiseGateThreshold:g.noiseGateThreshold??0.006,targetLevel:g.targetLevel??0.08}};var i0={balanced:{qualityProfile:"general",minSilenceMs:400,silenceMs:1400,speechThreshold:0.012,transcriptStabilityMs:1000},fast:{qualityProfile:"general",minSilenceMs:300,silenceMs:700,speechThreshold:0.015,transcriptStabilityMs:450},"long-form":{qualityProfile:"general",minSilenceMs:600,silenceMs:2200,speechThreshold:0.01,transcriptStabilityMs:1500}},n0={"accent-heavy":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},general:{},"noisy-room":{silenceMs:2000,speechThreshold:0.02,transcriptStabilityMs:1600},"short-command":{silenceMs:500,speechThreshold:0.016,transcriptStabilityMs:420}};var t=(g)=>{let A=g?.profile??"fast",C=g?.qualityProfile??"general",V=i0[A],c=n0[C],T=g?.silenceMs??c.silenceMs??V.silenceMs;return{profile:A,qualityProfile:C,minSilenceMs:Math.min(T,g?.minSilenceMs??c.minSilenceMs??V.minSilenceMs),silenceMs:T,speechThreshold:g?.speechThreshold??c.speechThreshold??V.speechThreshold,transcriptStabilityMs:g?.transcriptStabilityMs??c.transcriptStabilityMs??V.transcriptStabilityMs}};var o0={chat:{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"balanced",qualityProfile:"short-command"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"fast",qualityProfile:"general"}},dictation:{audioConditioning:{enabled:!0,maxGain:2.25,noiseGateAttenuation:0.05,noiseGateThreshold:0.003,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"accent-heavy"}},"guided-intake":{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"turn-scoped",turnDetection:{profile:"long-form",qualityProfile:"accent-heavy"}},"noisy-room":{audioConditioning:{enabled:!0,maxGain:3,noiseGateAttenuation:0.12,noiseGateThreshold:0.006,targetLevel:0.085},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:2100,speechThreshold:0.02,transcriptStabilityMs:1650}},"pstn-balanced":{audioConditioning:{enabled:!0,maxGain:2.8,noiseGateAttenuation:0.07,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:660,speechThreshold:0.012,transcriptStabilityMs:300}},"pstn-fast":{audioConditioning:{enabled:!0,maxGain:2.75,noiseGateAttenuation:0.06,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:620,speechThreshold:0.012,transcriptStabilityMs:280}},reliability:{audioConditioning:{enabled:!0,maxGain:2.9,noiseGateAttenuation:0.08,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room"}}},e=(g="default")=>{let A=o0[g];return{audioConditioning:p(A.audioConditioning),capture:{channelCount:A.capture?.channelCount??1,sampleRateHz:A.capture?.sampleRateHz??16000},connection:{...A.connection},name:g,sttLifecycle:A.sttLifecycle??"continuous",turnDetection:t(A.turnDetection)}};var m0=(g)=>({assistantAudio:[...g.assistantAudio],assistantStreamingText:g.assistantStreamingText,assistantTexts:[...g.assistantTexts],call:g.call,error:g.error,isConnected:g.isConnected,isRecording:!1,partial:g.partial,reconnect:g.reconnect,recordingError:null,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,turns:[...g.turns]}),g0=(g,A={})=>{let C=e(A.preset),V=a(g,{...C.connection,...A.connection}),c=null,T=m0(V),U=new Set,I=()=>{for(let D of U)D()},G=()=>{if(T={...T,assistantAudio:[...V.assistantAudio],assistantStreamingText:V.assistantStreamingText,assistantTexts:[...V.assistantTexts],call:V.call,error:V.error,isConnected:V.isConnected,partial:V.partial,reconnect:V.reconnect,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,turns:[...V.turns]},A.autoStopOnComplete!==!1&&T.status==="completed"&&T.isRecording)c?.stop(),c=null,T={...T,isRecording:!1};I()},W=V.subscribe(G);G();let _=()=>{if(c)return c;return c=l({channelCount:A.capture?.channelCount??C.capture.channelCount,onLevel:A.capture?.onLevel,onAudio:(D)=>{if(A.capture?.onAudio){A.capture.onAudio(D,V.sendAudio);return}V.sendAudio(D)},sampleRateHz:A.capture?.sampleRateHz??C.capture.sampleRateHz,...A.capture?.stream?{stream:A.capture.stream}:{}}),c},L=()=>{c?.stop(),c=null,T={...T,isRecording:!1},I()},$=async()=>{if(T.isRecording)return;try{T={...T,recordingError:null},I(),await _().start(),T={...T,isRecording:!0},I()}catch(D){throw c?.stop(),c=null,T={...T,isRecording:!1,recordingError:D instanceof Error?D.message:String(D)},I(),D}};return{close:(D)=>{W(),L(),V.close(D)},disconnect:()=>{W(),L(),V.disconnect()},startRecording:$,stopRecording:L,get assistantAudio(){return T.assistantAudio},get assistantTexts(){return T.assistantTexts},get assistantStreamingText(){return T.assistantStreamingText},bindHTMX(D){return d(V,D)},get call(){return T.call},callControl:(D)=>V.callControl(D),endTurn:()=>V.endTurn(),get error(){return T.error},getServerSnapshot:()=>T,getSnapshot:()=>T,get isConnected(){return T.isConnected},get isRecording(){return T.isRecording},get partial(){return T.partial},get reconnect(){return T.reconnect},get recordingError(){return T.recordingError},get scenarioId(){return T.scenarioId},sendAudio:(D)=>V.sendAudio(D),get sessionId(){return T.sessionId},get sessionMetadata(){return T.sessionMetadata},simulateDisconnect:()=>V.simulateDisconnect(),get status(){return T.status},subscribe:(D)=>{return U.add(D),()=>{U.delete(D)}},toggleRecording:async()=>{if(T.isRecording){L();return}await $()},get turns(){return T.turns}}};var K=(g)=>String(g).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'");var A0=(g)=>{if(!g.isConnected)return"idle";if(g.isPlaying)return"speaking";if(g.isRecording&&g.hasActivePartial)return"listening";if(g.isRecording)return"listening";if(g.lastTranscriptAt&&!g.lastAssistantAt)return"thinking";if(g.lastTranscriptAt&&g.lastAssistantAt&&g.lastTranscriptAt>g.lastAssistantAt)return"thinking";return"idle"};var r0={accent:"#3b82f6",background:"#0f172a",errorAccent:"#ef4444",fontFamily:'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',foreground:"#f8fafc",radius:16},u0={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},s0=(g,A)=>{switch(g){case"listening":return A.listening;case"speaking":return A.speaking;case"thinking":return A.thinking;case"idle":return A.idle}},V0=(g)=>{let A={...r0,...g.theme},C={...u0,...g.labels},V=g.state.assistantAudio.at(-1)?.receivedAt,c=g.state.turns.at(-1)?.committedAt,T=A0({hasActivePartial:g.state.partial.length>0,isConnected:g.state.isConnected,isPlaying:!1,isRecording:g.state.isRecording,lastAssistantAt:V,lastTranscriptAt:c}),U=!g.state.isConnected&&g.state.status!=="idle"&&!g.state.error,I=g.state.error?"Error":U?C.connecting:g.state.status==="completed"?C.callEnded:s0(T,C);return{agentState:T,classes:{container:`absolute-voice-widget absolute-voice-widget--${T}`,dot:`absolute-voice-widget__dot${g.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:g.state.isConnected,canMute:g.state.isRecording,canStart:!g.state.isRecording&&g.state.status!=="completed"},errorMessage:g.state.error??void 0,labels:C,partial:g.state.partial||void 0,statusLabel:I,theme:A,title:g.title??"Voice"}},a0=(g)=>typeof g==="number"?`${g}px`:g,C0=(g)=>{let A=g.theme,C=`background:${A.background};border-radius:${a0(A.radius)};color:${A.foreground};font-family:${A.fontFamily};min-width:240px;padding:20px 22px;`,V=`background:${g.errorMessage?A.errorAccent:g.agentState==="idle"?"rgba(148,163,184,0.6)":A.accent};border-radius:50%;height:10px;width:10px;`,c=[];if(g.controls.canStart)c.push(`<button type="button" data-action="start" style="background:${A.accent};border:none;border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.startCall)}</button>`);if(g.controls.canMute)c.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.mute)}</button>`);if(g.controls.canEnd)c.push(`<button type="button" data-action="end" style="background:${A.errorAccent};border:none;border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${g.agentState}" class="${K(g.classes.container)}" style="${C}">
|
|
1
|
+
(()=>{var{defineProperty:x,getOwnPropertyNames:L0,getOwnPropertyDescriptor:G0}=Object,W0=Object.prototype.hasOwnProperty;function D0(g){return this[g]}var S0=(g)=>{var A=(f??=new WeakMap).get(g),C;if(A)return A;if(A=x({},"__esModule",{value:!0}),g&&typeof g==="object"||typeof g==="function"){for(var V of L0(g))if(!W0.call(A,V))x(A,V,{get:D0.bind(g,V),enumerable:!(C=G0(g,V))||C.enumerable})}return f.set(g,A),A},f;var y0=(g)=>g;function X0(g,A){this[g]=y0.bind(null,A)}var O0=(g,A)=>{for(var C in A)x(g,C,{get:A[C],enumerable:!0,configurable:!0,set:X0.bind(A,C)})};var e0={};O0(e0,{mount:()=>c0,default:()=>gg,VOICE_EMBED_VERSION:()=>_0});var J0=(g)=>{if(typeof g!=="string")return g;return document.querySelector(g)},Y0=(g,A,C,V)=>{let T=A??g.getAttribute("hx-get")??"";if(!T)return"";let c=new URL(T,window.location.origin);if(V)c.searchParams.set(C,V);else c.searchParams.delete(C);return`${c.pathname}${c.search}${c.hash}`},d=(g,A)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let C=J0(A.element);if(!C)return()=>{};let V=A.eventName??"voice-refresh",T=A.sessionQueryParam??"sessionId",c=()=>{let I=window,G=Y0(C,A.route,T,g.sessionId);if(G)C.setAttribute("hx-get",G);I.htmx?.process?.(C),I.htmx?.trigger?.(C,V)},U=g.subscribe(c);return c(),()=>{U()}};var Z0=(g)=>Math.max(-1,Math.min(1,g)),h0=(g)=>{let A=new Int16Array(g.length);for(let C=0;C<g.length;C+=1){let V=Z0(g[C]??0);A[C]=V<0?V*32768:V*32767}return new Uint8Array(A.buffer)},w0=(g)=>{let A=g instanceof Uint8Array?g:new Uint8Array(g);if(A.byteLength<2)return 0;let C=new Int16Array(A.buffer,A.byteOffset,Math.floor(A.byteLength/2));if(C.length===0)return 0;let V=0;for(let T of C){let c=T/32768;V+=c*c}return Math.min(1,Math.max(0,Math.sqrt(V/C.length)*5.5))},Q0=(g,A,C)=>{if(A===C)return g;let V=A/C,T=Math.round(g.length/V),c=new Float32Array(T),U=0,I=0;while(U<c.length){let G=Math.round((U+1)*V),W=0,_=0;for(let L=I;L<G&&L<g.length;L+=1)W+=g[L]??0,_+=1;c[U]=_>0?W/_:0,U+=1,I=G}return c},l=(g)=>{let A=null,C=null,V=null,T=null,c=async()=>{if(!g.stream&&(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia))throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let I=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!I)throw Error("Browser microphone capture requires AudioContext support.");try{if(T=g.stream??await navigator.mediaDevices.getUserMedia({audio:{autoGainControl:!0,channelCount:g.channelCount??1,echoCancellation:!0,noiseSuppression:!0}}),A=new I,A.state==="suspended")await A.resume();C=A.createMediaStreamSource(T),V=A.createScriptProcessor(4096,1,1),V.onaudioprocess=(G)=>{let W=G.inputBuffer.getChannelData(0),_=Q0(W,A?.sampleRate??48000,g.sampleRateHz??16000),L=h0(_);g.onLevel?.(w0(L)),g.onAudio(L)},C.connect(V),V.connect(A.destination)}catch(G){throw U(),G}},U=()=>{V?.disconnect(),C?.disconnect(),T?.getTracks().forEach((I)=>I.stop()),A?.close(),g.onLevel?.(0),A=null,T=null,V=null,C=null};return{start:c,stop:U}};var k=(g)=>{if(typeof g==="string"&&g.trim())return g;if(g instanceof Error&&g.message.trim())return g.message;if(g&&typeof g==="object"){let A=g;for(let C of["message","reason","description"]){let V=A[C];if(typeof V==="string"&&V.trim())return V}if("error"in A)return k(A.error);if("cause"in A)return k(A.cause);try{return JSON.stringify(g)}catch{}}return"Unexpected error"},v=(g)=>{switch(g.type){case"audio":return{chunk:Uint8Array.from(atob(g.chunkBase64),(A)=>A.charCodeAt(0)),format:g.format,receivedAt:g.receivedAt,turnId:g.turnId,type:"audio"};case"assistant":return{text:g.text,turnId:g.turnId,type:"assistant"};case"assistant_delta":return{delta:g.delta,turnId:g.turnId,type:"assistant_delta"};case"complete":return{sessionId:g.sessionId,type:"complete"};case"connection":return{reconnect:g.reconnect,type:"connection"};case"call_lifecycle":return{event:g.event,sessionId:g.sessionId,type:"call_lifecycle"};case"error":return{message:k(g.message),recoverable:g.recoverable,type:"error"};case"call_control_ack":return null;case"final":return{transcript:g.transcript,type:"final"};case"partial":return{transcript:g.transcript,type:"partial"};case"replay":return{assistantTexts:g.assistantTexts,call:g.call,partial:g.partial,scenarioId:g.scenarioId,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,status:g.status,turns:g.turns,type:"replay"};case"session":return{sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,type:"session"};case"turn":return{turn:g.turn,type:"turn"};default:return null}};var _g=Math.PI*2;var P=(g,A,C,V)=>{g.push({code:C,message:V,severity:A})};var P0=(g)=>g.length===0?void 0:g.reduce((A,C)=>A+C,0)/g.length,M=(g)=>g.length===0?void 0:Math.max(...g);var X=(g,A)=>{let C=g[A];return typeof C==="number"&&Number.isFinite(C)?C:void 0},B=(g,A)=>{let C=g[A];return typeof C==="boolean"?C:void 0},J=(g,A)=>{let C=g[A];return typeof C==="string"?C:void 0},F=(g)=>String(g.id??J(g,"ssrc")??X(g,"ssrc")??J(g,"trackIdentifier")??J(g,"mid")??"unknown"),i=(g)=>g===void 0?void 0:g*1000;var K0=(g)=>{let A={};for(let[C,V]of Object.entries(g))if(V===null||typeof V==="boolean"||typeof V==="number"||typeof V==="string")A[C]=V;return A};var n=(g={})=>{let A=g.stats??[],C=[],V=A.filter((R)=>R.type==="inbound-rtp"&&J(R,"kind")!=="video"),T=A.filter((R)=>R.type==="outbound-rtp"&&J(R,"kind")!=="video"),c=A.filter((R)=>R.type==="candidate-pair"),U=A.filter((R)=>(R.type==="track"||R.type==="media-source")&&J(R,"kind")==="audio"),I=c.filter((R)=>B(R,"selected")===!0||B(R,"nominated")===!0||J(R,"state")==="succeeded").length,G=U.filter((R)=>J(R,"readyState")!=="ended"&&J(R,"trackState")!=="ended"&&B(R,"ended")!==!0).length,W=U.filter((R)=>J(R,"readyState")==="ended"||J(R,"trackState")==="ended"||B(R,"ended")===!0).length,_=V.reduce((R,O)=>R+(X(O,"packetsReceived")??0),0),L=T.reduce((R,O)=>R+(X(O,"packetsSent")??0),0),H=[...V,...T].reduce((R,O)=>R+Math.max(0,X(O,"packetsLost")??0),0),Z=_+H,E=Z===0?0:H/Z,D=V.reduce((R,O)=>R+(X(O,"bytesReceived")??0),0),h=T.reduce((R,O)=>R+(X(O,"bytesSent")??0),0),w=M(c.map((R)=>i(X(R,"currentRoundTripTime")??X(R,"roundTripTime"))).filter((R)=>R!==void 0)),Q=M([...V,...T].map((R)=>i(X(R,"jitter"))).filter((R)=>R!==void 0)),N=M(V.map((R)=>{let O=X(R,"jitterBufferDelay"),b=X(R,"jitterBufferEmittedCount");return O!==void 0&&b!==void 0&&b>0?O/b*1000:void 0}).filter((R)=>R!==void 0)),z=U.map((R)=>X(R,"audioLevel")).filter((R)=>R!==void 0);if(g.requireConnectedCandidatePair&&c.length>0&&I===0)P(C,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(g.requireLiveAudioTrack&&G===0)P(C,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(g.maxPacketLossRatio!==void 0&&E>g.maxPacketLossRatio)P(C,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(E)} above ${String(g.maxPacketLossRatio)}.`);if(g.maxRoundTripTimeMs!==void 0&&w!==void 0&&w>g.maxRoundTripTimeMs)P(C,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(w)}ms above ${String(g.maxRoundTripTimeMs)}ms.`);if(g.maxJitterMs!==void 0&&Q!==void 0&&Q>g.maxJitterMs)P(C,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(Q)}ms above ${String(g.maxJitterMs)}ms.`);return{activeCandidatePairs:I,audioLevelAverage:P0(z),bytesReceived:D,bytesSent:h,checkedAt:Date.now(),endedAudioTracks:W,inboundPackets:_,issues:C,jitterBufferDelayMs:N,jitterMs:Q,liveAudioTracks:G,outboundPackets:L,packetLossRatio:E,packetsLost:H,roundTripTimeMs:w,status:C.some((R)=>R.severity==="error")?"fail":C.length>0?"warn":"pass",totalStats:A.length}},o=async(g)=>{return[...(await g.peerConnection.getStats(g.selector??null)).values()].map(K0)};var m=(g={})=>{let A=g.stats??[],C=g.previousStats??[],V=[],T=new Map(C.map((H)=>[F(H),H])),U=A.filter((H)=>(H.type==="inbound-rtp"||H.type==="outbound-rtp")&&J(H,"kind")!=="video"&&J(H,"mediaType")!=="video").map((H)=>{let Z=H.type==="outbound-rtp"?"outbound":"inbound",E=Z==="outbound"?"packetsSent":"packetsReceived",D=Z==="outbound"?"bytesSent":"bytesReceived",h=T.get(F(H)),w=X(H,E),Q=h?X(h,E):void 0,N=X(H,D),z=h?X(h,D):void 0,R=H.timestamp!==void 0&&h?.timestamp!==void 0?H.timestamp-h.timestamp:void 0;return{bytesDelta:N!==void 0&&z!==void 0?N-z:void 0,currentPackets:w,direction:Z,id:F(H),packetDelta:w!==void 0&&Q!==void 0?w-Q:void 0,previousPackets:Q,timeDeltaMs:R}}),I=U.filter((H)=>H.direction==="inbound"),G=U.filter((H)=>H.direction==="outbound"),W=M(U.map((H)=>H.timeDeltaMs).filter((H)=>H!==void 0)),_=I.filter((H)=>g.maxInboundPacketStallMs!==void 0&&H.timeDeltaMs!==void 0&&H.timeDeltaMs>=g.maxInboundPacketStallMs&&H.packetDelta!==void 0&&H.packetDelta<=0).length,L=G.filter((H)=>g.maxOutboundPacketStallMs!==void 0&&H.timeDeltaMs!==void 0&&H.timeDeltaMs>=g.maxOutboundPacketStallMs&&H.packetDelta!==void 0&&H.packetDelta<=0).length;if(g.requireInboundAudio&&I.length===0)P(V,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(g.requireOutboundAudio&&G.length===0)P(V,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(g.maxGapMs!==void 0&&W!==void 0&&W>g.maxGapMs)P(V,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(W)}ms above ${String(g.maxGapMs)}ms.`);if(_>0)P(V,"error","media.webrtc_inbound_stalled",`${String(_)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(L>0)P(V,"error","media.webrtc_outbound_stalled",`${String(L)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:I.length,issues:V,maxObservedGapMs:W,outboundAudioStreams:G.length,stalledInboundStreams:_,stalledOutboundStreams:L,status:V.some((H)=>H.severity==="error")?"fail":V.length>0?"warn":"pass",streams:U,totalStats:A.length}};var E0="/api/voice/browser-media",N0=5000,q0=async(g)=>g.peerConnection??await g.getPeerConnection?.()??null,z0=async(g,A)=>{let C=A.fetch??globalThis.fetch;if(!C)return;await C(A.path??E0,{body:JSON.stringify(g),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},r=(g)=>{let A=null,C=[],V=async()=>{let U=await q0(g);if(!U)return;let I=await o({peerConnection:U}),G=n({...g,stats:I}),W=g.continuity===!1?void 0:m({...g.continuity,previousStats:C,stats:I}),_={at:Date.now(),continuity:W,report:G,scenarioId:g.getScenarioId?.()??null,sessionId:g.getSessionId?.()??null};return C=I,g.onReport?.(_),await z0(_,g),_},T=()=>{V().catch((U)=>{g.onError?.(U)})},c=()=>{if(A)clearInterval(A),A=null};return{close:c,reportOnce:V,stop:c,start:()=>{if(A)return;T(),A=setInterval(T,g.intervalMs??N0)}}};var b0=(g,A,C)=>Math.min(C,A*2**(Math.max(1,g)-1));var q=()=>{},B0=()=>Promise.resolve(),M0=()=>q,j0={callControl:B0,close:q,disconnect:q,endTurn:q,send:q,sendAudio:q,simulateDisconnect:q,subscribe:M0,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",start:()=>{}},x0=()=>crypto.randomUUID(),k0=(g,A,C,V)=>{let{hostname:T,port:c,protocol:U}=window.location,I=U==="https:"?"wss:":"ws:",G=c?`:${c}`:"",W=new URL(`${I}//${T}${G}${g}`);if(W.searchParams.set("sessionId",A),C)W.searchParams.set("scenarioId",C);for(let[_,L]of Object.entries(V))if(_!=="sessionId"&&_!=="scenarioId"&&L)W.searchParams.set(_,L);return W.toString()},F0=(g)=>{if(!g||typeof g!=="object"||!("type"in g))return!1;switch(g.type){case"audio":case"assistant":case"call_lifecycle":case"call_control_ack":case"complete":case"connection":case"error":case"final":case"partial":case"pong":case"replay":case"session":case"turn":return!0;default:return!1}},f0=(g)=>{if(typeof g.data!=="string")return null;try{let A=JSON.parse(g.data);return F0(A)?A:null}catch{return null}},u=(g,A={})=>{if(typeof window>"u")return j0;let C=new Set,V=new Map,T=A.reconnect!==!1,c=A.maxReconnectAttempts??15,U=A.reconnectMaxDelayMs??8000,I=A.pingInterval??30000,G=A.reconnectResetAfterMs??30000,W=($)=>b0($,500,U),_={isConnected:!1,pendingMessages:[],scenarioId:A.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectResetTimeout:null,reconnectTimeout:null,sessionId:A.sessionId??x0(),ws:null},L=($)=>{C.forEach((S)=>S($))},H=($)=>{C.forEach((S)=>S({message:$,recoverable:!1,type:"error"})),L({reconnect:{attempts:_.reconnectAttempts,maxAttempts:c,status:"exhausted"},type:"connection"})},Z=()=>{if(_.pingInterval)clearInterval(_.pingInterval),_.pingInterval=null;if(_.reconnectTimeout)clearTimeout(_.reconnectTimeout),_.reconnectTimeout=null;if(_.reconnectResetTimeout)clearTimeout(_.reconnectResetTimeout),_.reconnectResetTimeout=null},E=()=>{if(_.ws?.readyState!==1)return;while(_.pendingMessages.length>0){let $=_.pendingMessages.shift();if($!==void 0)_.ws.send($)}},D=($)=>{for(let S of V.values())clearTimeout(S.timeout),S.reject(Error($));V.clear()},h=()=>{_.reconnectAttempts+=1;let $=W(_.reconnectAttempts),S=Date.now()+$;L({reconnect:{attempts:_.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:c,nextAttemptAt:S,status:"reconnecting"},type:"connection"}),_.reconnectTimeout=setTimeout(async()=>{if(_.reconnectAttempts>c){H("Voice connection could not be restored.");return}try{await A.prepareReconnect?.({attempt:_.reconnectAttempts,path:g,scenarioId:_.scenarioId,sessionId:_.sessionId})}catch{if(_.reconnectAttempts<c)h();else H("Voice authorization could not be renewed for reconnect.");return}w()},$)},w=()=>{let $=new WebSocket(k0(g,_.sessionId,_.scenarioId,A.query??{}));$.binaryType="arraybuffer",$.onopen=()=>{if(_.ws!==$){$.close(1000);return}let S=_.reconnectAttempts>0;if(_.isConnected=!0,E(),S)L({reconnect:{attempts:_.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:c,status:"resumed"},type:"connection"}),_.reconnectResetTimeout=setTimeout(()=>{if(_.ws===$&&$.readyState===1)_.reconnectAttempts=0;_.reconnectResetTimeout=null},G);C.forEach((y)=>y({scenarioId:_.scenarioId??void 0,sessionId:_.sessionId,status:"active",type:"session"})),_.pingInterval=setInterval(()=>{if($.readyState===1)$.send(JSON.stringify({type:"ping"}))},I)},$.onmessage=(S)=>{if(_.ws!==$)return;let y=f0(S);if(!y)return;if(y.type==="session")_.sessionId=y.sessionId,_.scenarioId=y.scenarioId??_.scenarioId;if(y.type==="call_control_ack"){let Y=V.get(y.requestId);if(Y)if(clearTimeout(Y.timeout),V.delete(y.requestId),y.ok)Y.resolve();else Y.reject(Error(y.message??`${y.action} was not applied`))}C.forEach((Y)=>Y(y))},$.onclose=(S)=>{if(_.ws!==$)return;_.ws=null,_.isConnected=!1,Z();let y=T&&S.code!==1000&&S.code!==4401&&S.code!==4403&&_.reconnectAttempts<c,Y=S.code===4401||S.code===4403;if(Y)C.forEach((j)=>j({message:S.code===4401?"Voice authorization expired or was rejected.":"Voice authorization was forbidden.",recoverable:!1,type:"error"}));if(y)h();else if(T&&S.code!==1000)if(Y)L({reconnect:{attempts:_.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:c,status:"exhausted"},type:"connection"});else H("Voice connection could not be restored.")},_.ws=$},Q=($)=>{if(_.ws?.readyState===1){_.ws.send($);return}if(typeof $!=="string")return;if(_.pendingMessages.length>=100)_.pendingMessages.shift();_.pendingMessages.push($)},N=($)=>{Q(JSON.stringify($))},z=($={})=>{if($.sessionId)_.sessionId=$.sessionId;if($.scenarioId)_.scenarioId=$.scenarioId;N({scenarioId:_.scenarioId??void 0,sessionId:_.sessionId,type:"start"})},R=($)=>{Q($)},O=()=>{N({type:"end_turn"})},b=($)=>{let S=crypto.randomUUID(),{promise:y,reject:Y,resolve:j}=Promise.withResolvers(),U0=setTimeout(()=>{V.delete(S),Y(Error(`${$.action} acknowledgement timed out`))},5000);return V.set(S,{reject:Y,resolve:j,timeout:U0}),N({...$,requestId:S,type:"call_control"}),y},R0=($="client-close")=>{if(Z(),D("Voice connection closed"),_.ws){let S=_.ws;if(_.ws=null,S.readyState===1)S.send(JSON.stringify({reason:$,type:"close"}));S.close(1000)}_.isConnected=!1,C.clear()},$0=()=>{if(Z(),D("Voice connection disconnected"),_.ws){let $=_.ws;_.ws=null,$.close(1000)}_.isConnected=!1,C.clear()},H0=()=>{if(_.ws?.readyState===1)_.ws.close(4000,"absolutejs-voice-reconnect-proof")},I0=($)=>{return C.add($),()=>{C.delete($)}};return w(),{callControl:b,close:R0,disconnect:$0,endTurn:O,send:N,sendAudio:R,simulateDisconnect:H0,start:z,subscribe:I0,getReadyState:()=>_.ws?.readyState??3,getScenarioId:()=>_.scenarioId??"",getSessionId:()=>_.sessionId}};var d0=()=>({attempts:0,maxAttempts:0,status:"idle"}),l0=(g,A)=>{let C=A.trim().replace(/\s+/g," ");if(!C)return g;if(!g)return C;if(g===C||g.endsWith(C))return g;if(C.includes(g))return C;return`${g} ${C}`},v0=(g,A)=>{let C=A.trim().replace(/\s+/g," ");if(!g)return C;if(!C||g.endsWith(C))return g;return`${g} ${C}`},i0=()=>({assistantAudio:[],assistantStreamingText:"",assistantTexts:[],call:null,error:null,isConnected:!1,partial:"",reconnect:d0(),scenarioId:null,sessionId:null,sessionMetadata:null,status:"idle",turns:[]}),s=()=>{let g=i0(),A="",C=new Set,V=()=>{C.forEach((c)=>c())};return{dispatch:(c)=>{switch(c.type){case"audio":g={...g,assistantAudio:[...g.assistantAudio,{chunk:c.chunk,format:c.format,receivedAt:c.receivedAt,turnId:c.turnId}]};break;case"assistant":g={...g,assistantStreamingText:"",assistantTexts:[...g.assistantTexts,c.text]};break;case"assistant_delta":g={...g,assistantStreamingText:`${g.assistantStreamingText}${c.delta}`};break;case"complete":g={...g,sessionId:c.sessionId,status:"completed"};break;case"call_lifecycle":g={...g,call:{...g.call,disposition:c.event.type==="end"?c.event.disposition:g.call?.disposition,endedAt:c.event.type==="end"?c.event.at:g.call?.endedAt,events:[...g.call?.events??[],c.event],lastEventAt:c.event.at,startedAt:g.call?.startedAt??c.event.at},sessionId:c.sessionId};break;case"connected":g={...g,isConnected:!0,reconnect:g.reconnect.status==="reconnecting"?{...g.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:g.reconnect};break;case"connection":g={...g,reconnect:c.reconnect};break;case"disconnected":g={...g,isConnected:!1};break;case"error":g={...g,error:c.message,...c.recoverable===!1?{isConnected:!1,status:"failed"}:{}};break;case"final":A=l0(A,c.transcript.text),g={...g,partial:A};break;case"partial":g={...g,partial:v0(A,c.transcript.text)};break;case"replay":A=c.partial,g={...g,assistantStreamingText:"",assistantTexts:[...c.assistantTexts],call:c.call??null,error:null,isConnected:c.status==="active",partial:c.partial,reconnect:g.reconnect.status==="reconnecting"?{...g.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:g.reconnect,scenarioId:c.scenarioId??g.scenarioId,sessionId:c.sessionId,sessionMetadata:c.sessionMetadata??g.sessionMetadata,status:c.status,turns:[...c.turns]};break;case"session":g={...g,error:null,scenarioId:c.scenarioId??g.scenarioId,isConnected:c.status==="active",sessionId:c.sessionId,sessionMetadata:c.sessionMetadata??g.sessionMetadata,status:c.status};break;case"turn":A="",g={...g,partial:"",turns:[...g.turns,c.turn]};break}V()},getServerSnapshot:()=>g,getSnapshot:()=>g,subscribe:(c)=>{return C.add(c),()=>{C.delete(c)}}}};var a=(g,A={})=>{let C=u(g,A),V=s(),T=A.browserMedia&&typeof window<"u"?r({...A.browserMedia,getScenarioId:()=>A.browserMedia?A.browserMedia.getScenarioId?.()??C.getScenarioId():C.getScenarioId(),getSessionId:()=>A.browserMedia?A.browserMedia.getSessionId?.()??C.getSessionId():C.getSessionId()}):null,c=new Set,U=(_)=>Promise.resolve().then(()=>{if(!_?.sessionId&&!_?.scenarioId)return;C.start(_),T?.start()}),I=()=>{c.forEach((_)=>_())},G=()=>{if(!A.reconnectReportPath||typeof fetch>"u")return;let _=V.getSnapshot(),L=JSON.stringify({at:Date.now(),reconnect:_.reconnect,scenarioId:_.scenarioId,sessionId:C.getSessionId(),turnIds:_.turns.map((H)=>H.id)});fetch(A.reconnectReportPath,{body:L,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},W=C.subscribe((_)=>{let L=v(_);if(L){if(V.dispatch(L),_.type==="connection")G();I()}});return{start:U,get assistantAudio(){return V.getSnapshot().assistantAudio},get assistantTexts(){return V.getSnapshot().assistantTexts},get assistantStreamingText(){return V.getSnapshot().assistantStreamingText},get call(){return V.getSnapshot().call},callControl(_){return C.callControl(_)},close(_){W(),T?.close(),C.close(_),V.dispatch({type:"disconnected"}),I()},disconnect(){W(),T?.close(),C.disconnect(),V.dispatch({type:"disconnected"}),I()},endTurn(){C.endTurn()},get error(){return V.getSnapshot().error},getServerSnapshot(){return V.getServerSnapshot()},getSnapshot(){return V.getSnapshot()},get isConnected(){return V.getSnapshot().isConnected},get partial(){return V.getSnapshot().partial},get reconnect(){return V.getSnapshot().reconnect},get scenarioId(){return V.getSnapshot().scenarioId},sendAudio(_){C.sendAudio(_)},get sessionId(){return C.getSessionId()},get sessionMetadata(){return V.getSnapshot().sessionMetadata},simulateDisconnect(){C.simulateDisconnect()},get status(){return V.getSnapshot().status},subscribe(_){return c.add(_),()=>{c.delete(_)}},get turns(){return V.getSnapshot().turns}}};var p=(g)=>{if(!g||g.enabled===!1)return;return{enabled:!0,maxGain:g.maxGain??3,noiseGateAttenuation:g.noiseGateAttenuation??0.15,noiseGateThreshold:g.noiseGateThreshold??0.006,targetLevel:g.targetLevel??0.08}};var n0={balanced:{qualityProfile:"general",minSilenceMs:400,silenceMs:1400,speechThreshold:0.012,transcriptStabilityMs:1000},fast:{qualityProfile:"general",minSilenceMs:300,silenceMs:700,speechThreshold:0.015,transcriptStabilityMs:450},"long-form":{qualityProfile:"general",minSilenceMs:600,silenceMs:2200,speechThreshold:0.01,transcriptStabilityMs:1500}},o0={"accent-heavy":{silenceMs:1200,speechThreshold:0.01,transcriptStabilityMs:1200},general:{},"noisy-room":{silenceMs:2000,speechThreshold:0.02,transcriptStabilityMs:1600},"short-command":{silenceMs:500,speechThreshold:0.016,transcriptStabilityMs:420}};var t=(g)=>{let A=g?.profile??"fast",C=g?.qualityProfile??"general",V=n0[A],T=o0[C],c=g?.silenceMs??T.silenceMs??V.silenceMs;return{profile:A,qualityProfile:C,minSilenceMs:Math.min(c,g?.minSilenceMs??T.minSilenceMs??V.minSilenceMs),silenceMs:c,speechThreshold:g?.speechThreshold??T.speechThreshold??V.speechThreshold,transcriptStabilityMs:g?.transcriptStabilityMs??T.transcriptStabilityMs??V.transcriptStabilityMs}};var m0={chat:{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"balanced",qualityProfile:"short-command"}},default:{capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:10,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"fast",qualityProfile:"general"}},dictation:{audioConditioning:{enabled:!0,maxGain:2.25,noiseGateAttenuation:0.05,noiseGateThreshold:0.003,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"accent-heavy"}},"guided-intake":{audioConditioning:{enabled:!0,maxGain:2.5,noiseGateAttenuation:0,noiseGateThreshold:0.004,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:12,pingInterval:30000,reconnect:!0},sttLifecycle:"turn-scoped",turnDetection:{profile:"long-form",qualityProfile:"accent-heavy"}},"noisy-room":{audioConditioning:{enabled:!0,maxGain:3,noiseGateAttenuation:0.12,noiseGateThreshold:0.006,targetLevel:0.085},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:2100,speechThreshold:0.02,transcriptStabilityMs:1650}},"pstn-balanced":{audioConditioning:{enabled:!0,maxGain:2.8,noiseGateAttenuation:0.07,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:660,speechThreshold:0.012,transcriptStabilityMs:300}},"pstn-fast":{audioConditioning:{enabled:!0,maxGain:2.75,noiseGateAttenuation:0.06,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room",silenceMs:620,speechThreshold:0.012,transcriptStabilityMs:280}},reliability:{audioConditioning:{enabled:!0,maxGain:2.9,noiseGateAttenuation:0.08,noiseGateThreshold:0.005,targetLevel:0.08},capture:{channelCount:1,sampleRateHz:16000},connection:{maxReconnectAttempts:14,pingInterval:45000,reconnect:!0},sttLifecycle:"continuous",turnDetection:{profile:"long-form",qualityProfile:"noisy-room"}}},e=(g="default")=>{let A=m0[g];return{audioConditioning:p(A.audioConditioning),capture:{channelCount:A.capture?.channelCount??1,sampleRateHz:A.capture?.sampleRateHz??16000},connection:{...A.connection},name:g,sttLifecycle:A.sttLifecycle??"continuous",turnDetection:t(A.turnDetection)}};var r0=(g)=>({assistantAudio:[...g.assistantAudio],assistantStreamingText:g.assistantStreamingText,assistantTexts:[...g.assistantTexts],call:g.call,error:g.error,isConnected:g.isConnected,isRecording:!1,partial:g.partial,reconnect:g.reconnect,recordingError:null,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,turns:[...g.turns]}),g0=(g,A={})=>{let C=e(A.preset),V=a(g,{...C.connection,...A.connection}),T=null,c=r0(V),U=new Set,I=()=>{for(let D of U)D()},G=()=>{if(c={...c,assistantAudio:[...V.assistantAudio],assistantStreamingText:V.assistantStreamingText,assistantTexts:[...V.assistantTexts],call:V.call,error:V.error,isConnected:V.isConnected,partial:V.partial,reconnect:V.reconnect,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,turns:[...V.turns]},A.autoStopOnComplete!==!1&&c.status==="completed"&&c.isRecording)T?.stop(),T=null,c={...c,isRecording:!1};I()},W=V.subscribe(G);G();let _=()=>{if(T)return T;return T=l({channelCount:A.capture?.channelCount??C.capture.channelCount,onLevel:A.capture?.onLevel,onAudio:(D)=>{if(A.capture?.onAudio){A.capture.onAudio(D,V.sendAudio);return}V.sendAudio(D)},sampleRateHz:A.capture?.sampleRateHz??C.capture.sampleRateHz,...A.capture?.stream?{stream:A.capture.stream}:{}}),T},L=()=>{T?.stop(),T=null,c={...c,isRecording:!1},I()},H=async()=>{if(c.isRecording)return;try{c={...c,recordingError:null},I(),await _().start(),c={...c,isRecording:!0},I()}catch(D){throw T?.stop(),T=null,c={...c,isRecording:!1,recordingError:D instanceof Error?D.message:String(D)},I(),D}};return{close:(D)=>{W(),L(),V.close(D)},disconnect:()=>{W(),L(),V.disconnect()},startRecording:H,stopRecording:L,get assistantAudio(){return c.assistantAudio},get assistantTexts(){return c.assistantTexts},get assistantStreamingText(){return c.assistantStreamingText},bindHTMX(D){return d(V,D)},get call(){return c.call},callControl:(D)=>V.callControl(D),endTurn:()=>V.endTurn(),get error(){return c.error},getServerSnapshot:()=>c,getSnapshot:()=>c,get isConnected(){return c.isConnected},get isRecording(){return c.isRecording},get partial(){return c.partial},get reconnect(){return c.reconnect},get recordingError(){return c.recordingError},get scenarioId(){return c.scenarioId},sendAudio:(D)=>V.sendAudio(D),get sessionId(){return c.sessionId},get sessionMetadata(){return c.sessionMetadata},simulateDisconnect:()=>V.simulateDisconnect(),get status(){return c.status},subscribe:(D)=>{return U.add(D),()=>{U.delete(D)}},toggleRecording:async()=>{if(c.isRecording){L();return}await H()},get turns(){return c.turns}}};var K=(g)=>String(g).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'");var A0=(g)=>{if(!g.isConnected)return"idle";if(g.isPlaying)return"speaking";if(g.isRecording&&g.hasActivePartial)return"listening";if(g.isRecording)return"listening";if(g.lastTranscriptAt&&!g.lastAssistantAt)return"thinking";if(g.lastTranscriptAt&&g.lastAssistantAt&&g.lastTranscriptAt>g.lastAssistantAt)return"thinking";return"idle"};var u0={accent:"#3b82f6",background:"#0f172a",errorAccent:"#ef4444",fontFamily:'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',foreground:"#f8fafc",radius:16},s0={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},a0=(g,A)=>{switch(g){case"listening":return A.listening;case"speaking":return A.speaking;case"thinking":return A.thinking;case"idle":return A.idle}},V0=(g)=>{let A={...u0,...g.theme},C={...s0,...g.labels},V=g.state.assistantAudio.at(-1)?.receivedAt,T=g.state.turns.at(-1)?.committedAt,c=A0({hasActivePartial:g.state.partial.length>0,isConnected:g.state.isConnected,isPlaying:!1,isRecording:g.state.isRecording,lastAssistantAt:V,lastTranscriptAt:T}),U=!g.state.isConnected&&g.state.status!=="idle"&&!g.state.error,I=g.state.error?"Error":U?C.connecting:g.state.status==="completed"?C.callEnded:a0(c,C);return{agentState:c,classes:{container:`absolute-voice-widget absolute-voice-widget--${c}`,dot:`absolute-voice-widget__dot${g.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:g.state.isConnected,canMute:g.state.isRecording,canStart:!g.state.isRecording&&g.state.status!=="completed"},errorMessage:g.state.error??void 0,labels:C,partial:g.state.partial||void 0,statusLabel:I,theme:A,title:g.title??"Voice"}},p0=(g)=>typeof g==="number"?`${g}px`:g,C0=(g)=>{let A=g.theme,C=`background:${A.background};border-radius:${p0(A.radius)};color:${A.foreground};font-family:${A.fontFamily};min-width:240px;padding:20px 22px;`,V=`background:${g.errorMessage?A.errorAccent:g.agentState==="idle"?"rgba(148,163,184,0.6)":A.accent};border-radius:50%;height:10px;width:10px;`,T=[];if(g.controls.canStart)T.push(`<button type="button" data-action="start" style="background:${A.accent};border:none;border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.startCall)}</button>`);if(g.controls.canMute)T.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.mute)}</button>`);if(g.controls.canEnd)T.push(`<button type="button" data-action="end" style="background:${A.errorAccent};border:none;border-radius:12px;color:${A.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${K(g.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${g.agentState}" class="${K(g.classes.container)}" style="${C}">
|
|
2
2
|
<div style="align-items:center;display:flex;gap:10px;margin-bottom:12px;">
|
|
3
3
|
<span aria-hidden="true" class="${K(g.classes.dot)}" style="${V}"></span>
|
|
4
4
|
<strong style="font-size:15px;">${K(g.title)}</strong>
|
|
5
5
|
<span style="font-size:13px;margin-left:auto;opacity:0.7;">${K(g.statusLabel)}</span>
|
|
6
6
|
</div>
|
|
7
7
|
${g.partial?`<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">“${K(g.partial)}”</p>`:""}
|
|
8
|
-
<div style="display:flex;gap:10px;">${
|
|
8
|
+
<div style="display:flex;gap:10px;">${T.join("")}</div>
|
|
9
9
|
${g.errorMessage?`<p style="color:${A.errorAccent};font-size:12px;margin-top:12px;">${K(g.errorMessage)}</p>`:""}
|
|
10
|
-
</div>`};var
|
|
10
|
+
</div>`};var t0=(g)=>{if(typeof g!=="string")return g;let A=document.querySelector(g);if(!A)throw Error(`AbsoluteVoice.mount: no element matches "${g}"`);return A},c0=(g,A={})=>{let C=t0(g),V=g0(A.path??"/voice",A.controllerOptions),T=null,c=null,U=()=>{let G=V0({...A.labels!==void 0?{labels:A.labels}:{},state:{assistantAudio:V.assistantAudio,error:V.error,isConnected:V.isConnected,isRecording:V.isRecording,partial:V.partial,status:V.status,turns:V.turns},...A.theme!==void 0?{theme:A.theme}:{},...A.title!==void 0?{title:A.title}:{}});C.innerHTML=C0(G);for(let W of C.querySelectorAll("button[data-action]")){let{action:_}=W.dataset;W.addEventListener("click",()=>{if(_==="start")V.startRecording();else if(_==="mute")V.stopRecording();else if(_==="end")V.close()})}if(V.error&&V.error!==T)T=V.error,A.onError?.(V.error);if(V.status!==c)c=V.status,A.onStatusChange?.(V.status)},I=V.subscribe(U);if(U(),A.autoStart)V.startRecording();return{controller:V,async end(){await V.close()},mute(){V.stopRecording()},async start(){await V.startRecording()},unmount(){I(),V.close(),C.innerHTML=""}}},_0="0.0.22-beta.516",T0={mount:c0,version:_0};if(typeof globalThis<"u")globalThis.AbsoluteVoice=T0;var gg=T0;})();
|
package/dist/react/index.js
CHANGED
|
@@ -11541,6 +11541,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11541
11541
|
const emitConnection = (reconnect) => {
|
|
11542
11542
|
listeners.forEach((listener) => listener(reconnect));
|
|
11543
11543
|
};
|
|
11544
|
+
const emitTerminalFailure = (message) => {
|
|
11545
|
+
listeners.forEach((listener) => listener({
|
|
11546
|
+
message,
|
|
11547
|
+
recoverable: false,
|
|
11548
|
+
type: "error"
|
|
11549
|
+
}));
|
|
11550
|
+
emitConnection({
|
|
11551
|
+
reconnect: {
|
|
11552
|
+
attempts: state.reconnectAttempts,
|
|
11553
|
+
maxAttempts: maxReconnectAttempts,
|
|
11554
|
+
status: "exhausted"
|
|
11555
|
+
},
|
|
11556
|
+
type: "connection"
|
|
11557
|
+
});
|
|
11558
|
+
};
|
|
11544
11559
|
const clearTimers = () => {
|
|
11545
11560
|
if (state.pingInterval) {
|
|
11546
11561
|
clearInterval(state.pingInterval);
|
|
@@ -11589,14 +11604,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11589
11604
|
});
|
|
11590
11605
|
state.reconnectTimeout = setTimeout(async () => {
|
|
11591
11606
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
11592
|
-
|
|
11593
|
-
reconnect: {
|
|
11594
|
-
attempts: state.reconnectAttempts,
|
|
11595
|
-
maxAttempts: maxReconnectAttempts,
|
|
11596
|
-
status: "exhausted"
|
|
11597
|
-
},
|
|
11598
|
-
type: "connection"
|
|
11599
|
-
});
|
|
11607
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
11600
11608
|
return;
|
|
11601
11609
|
}
|
|
11602
11610
|
try {
|
|
@@ -11610,14 +11618,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11610
11618
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
11611
11619
|
scheduleReconnect();
|
|
11612
11620
|
} else {
|
|
11613
|
-
|
|
11614
|
-
reconnect: {
|
|
11615
|
-
attempts: state.reconnectAttempts,
|
|
11616
|
-
maxAttempts: maxReconnectAttempts,
|
|
11617
|
-
status: "exhausted"
|
|
11618
|
-
},
|
|
11619
|
-
type: "connection"
|
|
11620
|
-
});
|
|
11621
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
11621
11622
|
}
|
|
11622
11623
|
return;
|
|
11623
11624
|
}
|
|
@@ -11707,15 +11708,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11707
11708
|
if (reconnectable) {
|
|
11708
11709
|
scheduleReconnect();
|
|
11709
11710
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11711
|
+
if (authorizationFailure) {
|
|
11712
|
+
emitConnection({
|
|
11713
|
+
reconnect: {
|
|
11714
|
+
attempts: state.reconnectAttempts,
|
|
11715
|
+
lastDisconnectAt: Date.now(),
|
|
11716
|
+
maxAttempts: maxReconnectAttempts,
|
|
11717
|
+
status: "exhausted"
|
|
11718
|
+
},
|
|
11719
|
+
type: "connection"
|
|
11720
|
+
});
|
|
11721
|
+
} else {
|
|
11722
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
11723
|
+
}
|
|
11719
11724
|
}
|
|
11720
11725
|
};
|
|
11721
11726
|
state.ws = ws;
|
package/dist/svelte/index.js
CHANGED
|
@@ -869,6 +869,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
869
869
|
const emitConnection = (reconnect) => {
|
|
870
870
|
listeners.forEach((listener) => listener(reconnect));
|
|
871
871
|
};
|
|
872
|
+
const emitTerminalFailure = (message) => {
|
|
873
|
+
listeners.forEach((listener) => listener({
|
|
874
|
+
message,
|
|
875
|
+
recoverable: false,
|
|
876
|
+
type: "error"
|
|
877
|
+
}));
|
|
878
|
+
emitConnection({
|
|
879
|
+
reconnect: {
|
|
880
|
+
attempts: state.reconnectAttempts,
|
|
881
|
+
maxAttempts: maxReconnectAttempts,
|
|
882
|
+
status: "exhausted"
|
|
883
|
+
},
|
|
884
|
+
type: "connection"
|
|
885
|
+
});
|
|
886
|
+
};
|
|
872
887
|
const clearTimers = () => {
|
|
873
888
|
if (state.pingInterval) {
|
|
874
889
|
clearInterval(state.pingInterval);
|
|
@@ -917,14 +932,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
917
932
|
});
|
|
918
933
|
state.reconnectTimeout = setTimeout(async () => {
|
|
919
934
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
920
|
-
|
|
921
|
-
reconnect: {
|
|
922
|
-
attempts: state.reconnectAttempts,
|
|
923
|
-
maxAttempts: maxReconnectAttempts,
|
|
924
|
-
status: "exhausted"
|
|
925
|
-
},
|
|
926
|
-
type: "connection"
|
|
927
|
-
});
|
|
935
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
928
936
|
return;
|
|
929
937
|
}
|
|
930
938
|
try {
|
|
@@ -938,14 +946,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
938
946
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
939
947
|
scheduleReconnect();
|
|
940
948
|
} else {
|
|
941
|
-
|
|
942
|
-
reconnect: {
|
|
943
|
-
attempts: state.reconnectAttempts,
|
|
944
|
-
maxAttempts: maxReconnectAttempts,
|
|
945
|
-
status: "exhausted"
|
|
946
|
-
},
|
|
947
|
-
type: "connection"
|
|
948
|
-
});
|
|
949
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
949
950
|
}
|
|
950
951
|
return;
|
|
951
952
|
}
|
|
@@ -1035,15 +1036,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
1035
1036
|
if (reconnectable) {
|
|
1036
1037
|
scheduleReconnect();
|
|
1037
1038
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1039
|
+
if (authorizationFailure) {
|
|
1040
|
+
emitConnection({
|
|
1041
|
+
reconnect: {
|
|
1042
|
+
attempts: state.reconnectAttempts,
|
|
1043
|
+
lastDisconnectAt: Date.now(),
|
|
1044
|
+
maxAttempts: maxReconnectAttempts,
|
|
1045
|
+
status: "exhausted"
|
|
1046
|
+
},
|
|
1047
|
+
type: "connection"
|
|
1048
|
+
});
|
|
1049
|
+
} else {
|
|
1050
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
1051
|
+
}
|
|
1047
1052
|
}
|
|
1048
1053
|
};
|
|
1049
1054
|
state.ws = ws;
|
package/dist/testing/index.js
CHANGED
|
@@ -3090,6 +3090,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
3090
3090
|
const emitConnection = (reconnect) => {
|
|
3091
3091
|
listeners.forEach((listener) => listener(reconnect));
|
|
3092
3092
|
};
|
|
3093
|
+
const emitTerminalFailure = (message) => {
|
|
3094
|
+
listeners.forEach((listener) => listener({
|
|
3095
|
+
message,
|
|
3096
|
+
recoverable: false,
|
|
3097
|
+
type: "error"
|
|
3098
|
+
}));
|
|
3099
|
+
emitConnection({
|
|
3100
|
+
reconnect: {
|
|
3101
|
+
attempts: state.reconnectAttempts,
|
|
3102
|
+
maxAttempts: maxReconnectAttempts,
|
|
3103
|
+
status: "exhausted"
|
|
3104
|
+
},
|
|
3105
|
+
type: "connection"
|
|
3106
|
+
});
|
|
3107
|
+
};
|
|
3093
3108
|
const clearTimers = () => {
|
|
3094
3109
|
if (state.pingInterval) {
|
|
3095
3110
|
clearInterval(state.pingInterval);
|
|
@@ -3138,14 +3153,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
3138
3153
|
});
|
|
3139
3154
|
state.reconnectTimeout = setTimeout(async () => {
|
|
3140
3155
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
3141
|
-
|
|
3142
|
-
reconnect: {
|
|
3143
|
-
attempts: state.reconnectAttempts,
|
|
3144
|
-
maxAttempts: maxReconnectAttempts,
|
|
3145
|
-
status: "exhausted"
|
|
3146
|
-
},
|
|
3147
|
-
type: "connection"
|
|
3148
|
-
});
|
|
3156
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
3149
3157
|
return;
|
|
3150
3158
|
}
|
|
3151
3159
|
try {
|
|
@@ -3159,14 +3167,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
3159
3167
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
3160
3168
|
scheduleReconnect();
|
|
3161
3169
|
} else {
|
|
3162
|
-
|
|
3163
|
-
reconnect: {
|
|
3164
|
-
attempts: state.reconnectAttempts,
|
|
3165
|
-
maxAttempts: maxReconnectAttempts,
|
|
3166
|
-
status: "exhausted"
|
|
3167
|
-
},
|
|
3168
|
-
type: "connection"
|
|
3169
|
-
});
|
|
3170
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
3170
3171
|
}
|
|
3171
3172
|
return;
|
|
3172
3173
|
}
|
|
@@ -3256,15 +3257,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
3256
3257
|
if (reconnectable) {
|
|
3257
3258
|
scheduleReconnect();
|
|
3258
3259
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3260
|
+
if (authorizationFailure) {
|
|
3261
|
+
emitConnection({
|
|
3262
|
+
reconnect: {
|
|
3263
|
+
attempts: state.reconnectAttempts,
|
|
3264
|
+
lastDisconnectAt: Date.now(),
|
|
3265
|
+
maxAttempts: maxReconnectAttempts,
|
|
3266
|
+
status: "exhausted"
|
|
3267
|
+
},
|
|
3268
|
+
type: "connection"
|
|
3269
|
+
});
|
|
3270
|
+
} else {
|
|
3271
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
3272
|
+
}
|
|
3268
3273
|
}
|
|
3269
3274
|
};
|
|
3270
3275
|
state.ws = ws;
|
package/dist/vue/index.js
CHANGED
|
@@ -10937,6 +10937,21 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
10937
10937
|
const emitConnection = (reconnect) => {
|
|
10938
10938
|
listeners.forEach((listener) => listener(reconnect));
|
|
10939
10939
|
};
|
|
10940
|
+
const emitTerminalFailure = (message) => {
|
|
10941
|
+
listeners.forEach((listener) => listener({
|
|
10942
|
+
message,
|
|
10943
|
+
recoverable: false,
|
|
10944
|
+
type: "error"
|
|
10945
|
+
}));
|
|
10946
|
+
emitConnection({
|
|
10947
|
+
reconnect: {
|
|
10948
|
+
attempts: state.reconnectAttempts,
|
|
10949
|
+
maxAttempts: maxReconnectAttempts,
|
|
10950
|
+
status: "exhausted"
|
|
10951
|
+
},
|
|
10952
|
+
type: "connection"
|
|
10953
|
+
});
|
|
10954
|
+
};
|
|
10940
10955
|
const clearTimers = () => {
|
|
10941
10956
|
if (state.pingInterval) {
|
|
10942
10957
|
clearInterval(state.pingInterval);
|
|
@@ -10985,14 +11000,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
10985
11000
|
});
|
|
10986
11001
|
state.reconnectTimeout = setTimeout(async () => {
|
|
10987
11002
|
if (state.reconnectAttempts > maxReconnectAttempts) {
|
|
10988
|
-
|
|
10989
|
-
reconnect: {
|
|
10990
|
-
attempts: state.reconnectAttempts,
|
|
10991
|
-
maxAttempts: maxReconnectAttempts,
|
|
10992
|
-
status: "exhausted"
|
|
10993
|
-
},
|
|
10994
|
-
type: "connection"
|
|
10995
|
-
});
|
|
11003
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
10996
11004
|
return;
|
|
10997
11005
|
}
|
|
10998
11006
|
try {
|
|
@@ -11006,14 +11014,7 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11006
11014
|
if (state.reconnectAttempts < maxReconnectAttempts) {
|
|
11007
11015
|
scheduleReconnect();
|
|
11008
11016
|
} else {
|
|
11009
|
-
|
|
11010
|
-
reconnect: {
|
|
11011
|
-
attempts: state.reconnectAttempts,
|
|
11012
|
-
maxAttempts: maxReconnectAttempts,
|
|
11013
|
-
status: "exhausted"
|
|
11014
|
-
},
|
|
11015
|
-
type: "connection"
|
|
11016
|
-
});
|
|
11017
|
+
emitTerminalFailure("Voice authorization could not be renewed for reconnect.");
|
|
11017
11018
|
}
|
|
11018
11019
|
return;
|
|
11019
11020
|
}
|
|
@@ -11103,15 +11104,19 @@ var createVoiceConnection = (path, options = {}) => {
|
|
|
11103
11104
|
if (reconnectable) {
|
|
11104
11105
|
scheduleReconnect();
|
|
11105
11106
|
} else if (shouldReconnect && event.code !== WS_NORMAL_CLOSURE) {
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11107
|
+
if (authorizationFailure) {
|
|
11108
|
+
emitConnection({
|
|
11109
|
+
reconnect: {
|
|
11110
|
+
attempts: state.reconnectAttempts,
|
|
11111
|
+
lastDisconnectAt: Date.now(),
|
|
11112
|
+
maxAttempts: maxReconnectAttempts,
|
|
11113
|
+
status: "exhausted"
|
|
11114
|
+
},
|
|
11115
|
+
type: "connection"
|
|
11116
|
+
});
|
|
11117
|
+
} else {
|
|
11118
|
+
emitTerminalFailure("Voice connection could not be restored.");
|
|
11119
|
+
}
|
|
11115
11120
|
}
|
|
11116
11121
|
};
|
|
11117
11122
|
state.ws = ws;
|