@absolutejs/voice 0.0.22-beta.661 → 0.0.22-beta.662

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.
@@ -525,6 +525,8 @@ var serverMessageToAction = (message) => {
525
525
  };
526
526
  case "session":
527
527
  return {
528
+ paused: message.paused,
529
+ pauseExpiresAt: message.pauseExpiresAt,
528
530
  sessionId: message.sessionId,
529
531
  sessionMetadata: message.sessionMetadata,
530
532
  scenarioId: message.scenarioId,
@@ -1115,6 +1117,7 @@ var createInitialState = () => ({
1115
1117
  call: null,
1116
1118
  error: null,
1117
1119
  isConnected: false,
1120
+ paused: false,
1118
1121
  partial: "",
1119
1122
  reconnect: createInitialReconnectState(),
1120
1123
  scenarioId: null,
@@ -1251,6 +1254,8 @@ var createVoiceStreamStore = () => {
1251
1254
  state = {
1252
1255
  ...state,
1253
1256
  error: null,
1257
+ paused: action.paused ?? false,
1258
+ pauseExpiresAt: action.pauseExpiresAt,
1254
1259
  scenarioId: action.scenarioId ?? state.scenarioId,
1255
1260
  isConnected: action.status === "active",
1256
1261
  sessionId: action.sessionId,
@@ -1387,6 +1392,12 @@ var createVoiceStream = (path, options = {}) => {
1387
1392
  get partial() {
1388
1393
  return store.getSnapshot().partial;
1389
1394
  },
1395
+ get paused() {
1396
+ return store.getSnapshot().paused;
1397
+ },
1398
+ get pauseExpiresAt() {
1399
+ return store.getSnapshot().pauseExpiresAt;
1400
+ },
1390
1401
  get reconnect() {
1391
1402
  return store.getSnapshot().reconnect;
1392
1403
  },
@@ -1750,6 +1761,8 @@ var createInitialState2 = (stream) => ({
1750
1761
  error: stream.error,
1751
1762
  isConnected: stream.isConnected,
1752
1763
  isRecording: false,
1764
+ paused: stream.paused,
1765
+ pauseExpiresAt: stream.pauseExpiresAt,
1753
1766
  partial: stream.partial,
1754
1767
  reconnect: stream.reconnect,
1755
1768
  recordingError: null,
@@ -1785,6 +1798,8 @@ var createVoiceController = (path, options = {}) => {
1785
1798
  call: stream.call,
1786
1799
  error: stream.error,
1787
1800
  isConnected: stream.isConnected,
1801
+ paused: stream.paused,
1802
+ pauseExpiresAt: stream.pauseExpiresAt,
1788
1803
  partial: stream.partial,
1789
1804
  reconnect: stream.reconnect,
1790
1805
  sessionId: stream.sessionId,
@@ -1932,6 +1947,12 @@ var createVoiceController = (path, options = {}) => {
1932
1947
  get partial() {
1933
1948
  return state.partial;
1934
1949
  },
1950
+ get paused() {
1951
+ return state.paused;
1952
+ },
1953
+ get pauseExpiresAt() {
1954
+ return state.pauseExpiresAt;
1955
+ },
1935
1956
  get reconnect() {
1936
1957
  return state.reconnect;
1937
1958
  },
@@ -20,6 +20,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
20
20
  sessionMetadata?: undefined;
21
21
  status?: undefined;
22
22
  turns?: undefined;
23
+ paused?: undefined;
24
+ pauseExpiresAt?: undefined;
23
25
  turn?: undefined;
24
26
  } | {
25
27
  text: string;
@@ -42,6 +44,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
42
44
  sessionMetadata?: undefined;
43
45
  status?: undefined;
44
46
  turns?: undefined;
47
+ paused?: undefined;
48
+ pauseExpiresAt?: undefined;
45
49
  turn?: undefined;
46
50
  } | {
47
51
  delta: string;
@@ -64,6 +68,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
64
68
  sessionMetadata?: undefined;
65
69
  status?: undefined;
66
70
  turns?: undefined;
71
+ paused?: undefined;
72
+ pauseExpiresAt?: undefined;
67
73
  turn?: undefined;
68
74
  } | {
69
75
  sessionId: string;
@@ -86,6 +92,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
86
92
  sessionMetadata?: undefined;
87
93
  status?: undefined;
88
94
  turns?: undefined;
95
+ paused?: undefined;
96
+ pauseExpiresAt?: undefined;
89
97
  turn?: undefined;
90
98
  } | {
91
99
  reconnect: import("..").VoiceReconnectClientState;
@@ -108,6 +116,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
108
116
  sessionMetadata?: undefined;
109
117
  status?: undefined;
110
118
  turns?: undefined;
119
+ paused?: undefined;
120
+ pauseExpiresAt?: undefined;
111
121
  turn?: undefined;
112
122
  } | {
113
123
  event: import("..").VoiceCallLifecycleEvent;
@@ -130,6 +140,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
130
140
  sessionMetadata?: undefined;
131
141
  status?: undefined;
132
142
  turns?: undefined;
143
+ paused?: undefined;
144
+ pauseExpiresAt?: undefined;
133
145
  turn?: undefined;
134
146
  } | {
135
147
  message: string;
@@ -152,6 +164,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
152
164
  sessionMetadata?: undefined;
153
165
  status?: undefined;
154
166
  turns?: undefined;
167
+ paused?: undefined;
168
+ pauseExpiresAt?: undefined;
155
169
  turn?: undefined;
156
170
  } | {
157
171
  transcript: import("..").Transcript;
@@ -174,6 +188,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
174
188
  sessionMetadata?: undefined;
175
189
  status?: undefined;
176
190
  turns?: undefined;
191
+ paused?: undefined;
192
+ pauseExpiresAt?: undefined;
177
193
  turn?: undefined;
178
194
  } | {
179
195
  transcript: import("..").Transcript;
@@ -196,6 +212,8 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
196
212
  sessionMetadata?: undefined;
197
213
  status?: undefined;
198
214
  turns?: undefined;
215
+ paused?: undefined;
216
+ pauseExpiresAt?: undefined;
199
217
  turn?: undefined;
200
218
  } | {
201
219
  assistantTexts: string[];
@@ -218,8 +236,12 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
218
236
  message?: undefined;
219
237
  recoverable?: undefined;
220
238
  transcript?: undefined;
239
+ paused?: undefined;
240
+ pauseExpiresAt?: undefined;
221
241
  turn?: undefined;
222
242
  } | {
243
+ paused: boolean | undefined;
244
+ pauseExpiresAt: number | undefined;
223
245
  sessionId: string;
224
246
  sessionMetadata: Record<string, unknown> | undefined;
225
247
  scenarioId: string | undefined;
@@ -263,4 +285,6 @@ export declare const serverMessageToAction: <TResult = unknown>(message: VoiceSe
263
285
  sessionMetadata?: undefined;
264
286
  status?: undefined;
265
287
  turns?: undefined;
288
+ paused?: undefined;
289
+ pauseExpiresAt?: undefined;
266
290
  } | null;
@@ -293,6 +293,8 @@ var serverMessageToAction = (message) => {
293
293
  };
294
294
  case "session":
295
295
  return {
296
+ paused: message.paused,
297
+ pauseExpiresAt: message.pauseExpiresAt,
296
298
  sessionId: message.sessionId,
297
299
  sessionMetadata: message.sessionMetadata,
298
300
  scenarioId: message.scenarioId,
@@ -1032,6 +1034,7 @@ var createInitialState = () => ({
1032
1034
  call: null,
1033
1035
  error: null,
1034
1036
  isConnected: false,
1037
+ paused: false,
1035
1038
  partial: "",
1036
1039
  reconnect: createInitialReconnectState(),
1037
1040
  scenarioId: null,
@@ -1168,6 +1171,8 @@ var createVoiceStreamStore = () => {
1168
1171
  state = {
1169
1172
  ...state,
1170
1173
  error: null,
1174
+ paused: action.paused ?? false,
1175
+ pauseExpiresAt: action.pauseExpiresAt,
1171
1176
  scenarioId: action.scenarioId ?? state.scenarioId,
1172
1177
  isConnected: action.status === "active",
1173
1178
  sessionId: action.sessionId,
@@ -1304,6 +1309,12 @@ var createVoiceStream = (path, options = {}) => {
1304
1309
  get partial() {
1305
1310
  return store.getSnapshot().partial;
1306
1311
  },
1312
+ get paused() {
1313
+ return store.getSnapshot().paused;
1314
+ },
1315
+ get pauseExpiresAt() {
1316
+ return store.getSnapshot().pauseExpiresAt;
1317
+ },
1307
1318
  get reconnect() {
1308
1319
  return store.getSnapshot().reconnect;
1309
1320
  },
@@ -1630,6 +1641,8 @@ var createInitialState2 = (stream) => ({
1630
1641
  error: stream.error,
1631
1642
  isConnected: stream.isConnected,
1632
1643
  isRecording: false,
1644
+ paused: stream.paused,
1645
+ pauseExpiresAt: stream.pauseExpiresAt,
1633
1646
  partial: stream.partial,
1634
1647
  reconnect: stream.reconnect,
1635
1648
  recordingError: null,
@@ -1665,6 +1678,8 @@ var createVoiceController = (path, options = {}) => {
1665
1678
  call: stream.call,
1666
1679
  error: stream.error,
1667
1680
  isConnected: stream.isConnected,
1681
+ paused: stream.paused,
1682
+ pauseExpiresAt: stream.pauseExpiresAt,
1668
1683
  partial: stream.partial,
1669
1684
  reconnect: stream.reconnect,
1670
1685
  sessionId: stream.sessionId,
@@ -1812,6 +1827,12 @@ var createVoiceController = (path, options = {}) => {
1812
1827
  get partial() {
1813
1828
  return state.partial;
1814
1829
  },
1830
+ get paused() {
1831
+ return state.paused;
1832
+ },
1833
+ get pauseExpiresAt() {
1834
+ return state.pauseExpiresAt;
1835
+ },
1815
1836
  get reconnect() {
1816
1837
  return state.reconnect;
1817
1838
  },
@@ -1390,6 +1390,8 @@ var serverMessageToAction = (message) => {
1390
1390
  };
1391
1391
  case "session":
1392
1392
  return {
1393
+ paused: message.paused,
1394
+ pauseExpiresAt: message.pauseExpiresAt,
1393
1395
  sessionId: message.sessionId,
1394
1396
  sessionMetadata: message.sessionMetadata,
1395
1397
  scenarioId: message.scenarioId,
@@ -1518,6 +1520,7 @@ var createInitialState2 = () => ({
1518
1520
  call: null,
1519
1521
  error: null,
1520
1522
  isConnected: false,
1523
+ paused: false,
1521
1524
  partial: "",
1522
1525
  reconnect: createInitialReconnectState(),
1523
1526
  scenarioId: null,
@@ -1654,6 +1657,8 @@ var createVoiceStreamStore = () => {
1654
1657
  state = {
1655
1658
  ...state,
1656
1659
  error: null,
1660
+ paused: action.paused ?? false,
1661
+ pauseExpiresAt: action.pauseExpiresAt,
1657
1662
  scenarioId: action.scenarioId ?? state.scenarioId,
1658
1663
  isConnected: action.status === "active",
1659
1664
  sessionId: action.sessionId,
@@ -1790,6 +1795,12 @@ var createVoiceStream = (path, options = {}) => {
1790
1795
  get partial() {
1791
1796
  return store.getSnapshot().partial;
1792
1797
  },
1798
+ get paused() {
1799
+ return store.getSnapshot().paused;
1800
+ },
1801
+ get pauseExpiresAt() {
1802
+ return store.getSnapshot().pauseExpiresAt;
1803
+ },
1793
1804
  get reconnect() {
1794
1805
  return store.getSnapshot().reconnect;
1795
1806
  },
@@ -2346,6 +2357,8 @@ var createInitialState3 = (stream) => ({
2346
2357
  error: stream.error,
2347
2358
  isConnected: stream.isConnected,
2348
2359
  isRecording: false,
2360
+ paused: stream.paused,
2361
+ pauseExpiresAt: stream.pauseExpiresAt,
2349
2362
  partial: stream.partial,
2350
2363
  reconnect: stream.reconnect,
2351
2364
  recordingError: null,
@@ -2381,6 +2394,8 @@ var createVoiceController = (path, options = {}) => {
2381
2394
  call: stream.call,
2382
2395
  error: stream.error,
2383
2396
  isConnected: stream.isConnected,
2397
+ paused: stream.paused,
2398
+ pauseExpiresAt: stream.pauseExpiresAt,
2384
2399
  partial: stream.partial,
2385
2400
  reconnect: stream.reconnect,
2386
2401
  sessionId: stream.sessionId,
@@ -2528,6 +2543,12 @@ var createVoiceController = (path, options = {}) => {
2528
2543
  get partial() {
2529
2544
  return state.partial;
2530
2545
  },
2546
+ get paused() {
2547
+ return state.paused;
2548
+ },
2549
+ get pauseExpiresAt() {
2550
+ return state.pauseExpiresAt;
2551
+ },
2531
2552
  get reconnect() {
2532
2553
  return state.reconnect;
2533
2554
  },
@@ -1533,6 +1533,8 @@ export type VoiceHTMXOptions<TSession extends VoiceSessionRecord = VoiceSessionR
1533
1533
  export type VoiceHTMXConfig<TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = VoiceHTMXRenderer<TSession, TResult> | VoiceHTMXOptions<TSession, TResult>;
1534
1534
  export type VoiceStreamState<TResult = unknown> = {
1535
1535
  call: VoiceCallLifecycleState | null;
1536
+ paused: boolean;
1537
+ pauseExpiresAt?: number;
1536
1538
  sessionMetadata: Record<string, unknown> | null;
1537
1539
  sessionId: string | null;
1538
1540
  scenarioId: string | null;
@@ -1553,6 +1555,8 @@ export type VoiceStreamState<TResult = unknown> = {
1553
1555
  };
1554
1556
  export type VoiceStream<TResult = unknown> = {
1555
1557
  call: VoiceCallLifecycleState | null;
1558
+ paused: boolean;
1559
+ pauseExpiresAt?: number;
1556
1560
  callControl: (message: Omit<VoiceClientCallControlMessage, "requestId" | "type">) => Promise<void>;
1557
1561
  close: (reason?: string) => void;
1558
1562
  /** Release the transport without terminally completing the server session. */
@@ -1650,6 +1654,8 @@ export type VoiceBargeInBinding = {
1650
1654
  export type VoiceController<TResult = unknown> = {
1651
1655
  bindHTMX: (options: VoiceHTMXBindingOptions) => () => void;
1652
1656
  call: VoiceCallLifecycleState | null;
1657
+ paused: boolean;
1658
+ pauseExpiresAt?: number;
1653
1659
  callControl: (message: Omit<VoiceClientCallControlMessage, "requestId" | "type">) => Promise<void>;
1654
1660
  close: (reason?: string) => void;
1655
1661
  /** Release the transport while leaving the server session resumable. */
@@ -290,6 +290,8 @@ var serverMessageToAction = (message) => {
290
290
  };
291
291
  case "session":
292
292
  return {
293
+ paused: message.paused,
294
+ pauseExpiresAt: message.pauseExpiresAt,
293
295
  sessionId: message.sessionId,
294
296
  sessionMetadata: message.sessionMetadata,
295
297
  scenarioId: message.scenarioId,
@@ -1029,6 +1031,7 @@ var createInitialState = () => ({
1029
1031
  call: null,
1030
1032
  error: null,
1031
1033
  isConnected: false,
1034
+ paused: false,
1032
1035
  partial: "",
1033
1036
  reconnect: createInitialReconnectState(),
1034
1037
  scenarioId: null,
@@ -1165,6 +1168,8 @@ var createVoiceStreamStore = () => {
1165
1168
  state = {
1166
1169
  ...state,
1167
1170
  error: null,
1171
+ paused: action.paused ?? false,
1172
+ pauseExpiresAt: action.pauseExpiresAt,
1168
1173
  scenarioId: action.scenarioId ?? state.scenarioId,
1169
1174
  isConnected: action.status === "active",
1170
1175
  sessionId: action.sessionId,
@@ -1301,6 +1306,12 @@ var createVoiceStream = (path, options = {}) => {
1301
1306
  get partial() {
1302
1307
  return store.getSnapshot().partial;
1303
1308
  },
1309
+ get paused() {
1310
+ return store.getSnapshot().paused;
1311
+ },
1312
+ get pauseExpiresAt() {
1313
+ return store.getSnapshot().pauseExpiresAt;
1314
+ },
1304
1315
  get reconnect() {
1305
1316
  return store.getSnapshot().reconnect;
1306
1317
  },
@@ -1627,6 +1638,8 @@ var createInitialState2 = (stream) => ({
1627
1638
  error: stream.error,
1628
1639
  isConnected: stream.isConnected,
1629
1640
  isRecording: false,
1641
+ paused: stream.paused,
1642
+ pauseExpiresAt: stream.pauseExpiresAt,
1630
1643
  partial: stream.partial,
1631
1644
  reconnect: stream.reconnect,
1632
1645
  recordingError: null,
@@ -1662,6 +1675,8 @@ var createVoiceController = (path, options = {}) => {
1662
1675
  call: stream.call,
1663
1676
  error: stream.error,
1664
1677
  isConnected: stream.isConnected,
1678
+ paused: stream.paused,
1679
+ pauseExpiresAt: stream.pauseExpiresAt,
1665
1680
  partial: stream.partial,
1666
1681
  reconnect: stream.reconnect,
1667
1682
  sessionId: stream.sessionId,
@@ -1809,6 +1824,12 @@ var createVoiceController = (path, options = {}) => {
1809
1824
  get partial() {
1810
1825
  return state.partial;
1811
1826
  },
1827
+ get paused() {
1828
+ return state.paused;
1829
+ },
1830
+ get pauseExpiresAt() {
1831
+ return state.pauseExpiresAt;
1832
+ },
1812
1833
  get reconnect() {
1813
1834
  return state.reconnect;
1814
1835
  },
@@ -1,10 +1,10 @@
1
- (()=>{var{defineProperty:k,getOwnPropertyNames:w0,getOwnPropertyDescriptor:J0}=Object,S0=Object.prototype.hasOwnProperty;function Y0(V){return this[V]}var Z0=(V)=>{var g=(l??=new WeakMap).get(V),C;if(g)return g;if(g=k({},"__esModule",{value:!0}),V&&typeof V==="object"||typeof V==="function"){for(var A of w0(V))if(!S0.call(g,A))k(g,A,{get:Y0.bind(V,A),enumerable:!(C=J0(V,A))||C.enumerable})}return l.set(V,g),g},l;var y0=(V)=>V;function h0(V,g){this[V]=y0.bind(null,g)}var Q0=(V,g)=>{for(var C in g)k(V,C,{get:g[C],enumerable:!0,configurable:!0,set:h0.bind(g,C)})};var _V={};Q0(_V,{mount:()=>$0,default:()=>TV,VOICE_EMBED_VERSION:()=>R0});var K0=(V)=>{if(typeof V!=="string")return V;return document.querySelector(V)},c0=(V,g,C,A)=>{let R=g??V.getAttribute("hx-get")??"";if(!R)return"";let _=new URL(R,window.location.origin);if(A)_.searchParams.set(C,A);else _.searchParams.delete(C);return`${_.pathname}${_.search}${_.hash}`},d=(V,g)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let C=K0(g.element);if(!C)return()=>{};let A=g.eventName??"voice-refresh",R=g.sessionQueryParam??"sessionId",_=()=>{let X=window,H=c0(C,g.route,R,V.sessionId);if(H)C.setAttribute("hx-get",H);X.htmx?.process?.(C),X.htmx?.trigger?.(C,A)},D=V.subscribe(_);return _(),()=>{D()}};var E0=(V)=>Math.max(-1,Math.min(1,V)),q0=(V)=>{let g=new Int16Array(V.length);for(let C=0;C<V.length;C+=1){let A=E0(V[C]??0);g[C]=A<0?A*32768:A*32767}return new Uint8Array(g.buffer)},N0=(V)=>{let g=V instanceof Uint8Array?V:new Uint8Array(V);if(g.byteLength<2)return 0;let C=new Int16Array(g.buffer,g.byteOffset,Math.floor(g.byteLength/2));if(C.length===0)return 0;let A=0;for(let R of C){let _=R/32768;A+=_*_}return Math.min(1,Math.max(0,Math.sqrt(A/C.length)*5.5))},z0=(V,g,C)=>{if(g===C)return V;let A=g/C,R=Math.round(V.length/A),_=new Float32Array(R),D=0,X=0;while(D<_.length){let H=Math.round((D+1)*A),O=0,L=0;for(let W=X;W<H&&W<V.length;W+=1)O+=V[W]??0,L+=1;_[D]=L>0?O/L:0,D+=1,X=H}return _},v=(V)=>{let g=null,C=null,A=null,R=null,_=0,D=null,X=(L)=>{L.processorNode?.disconnect(),L.sourceNode?.disconnect(),L.mediaStream?.getTracks().forEach((W)=>W.stop()),L.audioContext?.close()};return{start:()=>{if(R)return Promise.resolve();if(D)return D;let L=++_,U=(async()=>{if(!V.stream&&(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia))throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let T=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!T)throw Error("Browser microphone capture requires AudioContext support.");let J=null,y=null,Z=null,Q=null;try{if(y=V.stream??await navigator.mediaDevices.getUserMedia({audio:{autoGainControl:!0,channelCount:V.channelCount??1,echoCancellation:!0,noiseSuppression:!0}}),L!==_)throw Error("Microphone capture stopped during startup.");if(J=new T,J.state==="suspended")await J.resume();if(L!==_)throw Error("Microphone capture stopped during startup.");if(Q=J.createMediaStreamSource(y),Z=J.createScriptProcessor(4096,1,1),Z.onaudioprocess=(G)=>{let c=G.inputBuffer.getChannelData(0),q=z0(c,J?.sampleRate??48000,V.sampleRateHz??16000),$=q0(q);V.onLevel?.(N0($)),V.onAudio($)},Q.connect(Z),Z.connect(J.destination),L!==_)throw Error("Microphone capture stopped during startup.");g=J,R=y,A=Z,C=Q}catch(G){throw X({audioContext:J,mediaStream:y,processorNode:Z,sourceNode:Q}),G}})().finally(()=>{if(D===U)D=null});return D=U,U},stop:()=>{_+=1,X({audioContext:g,mediaStream:R,processorNode:A,sourceNode:C}),V.onLevel?.(0),g=null,R=null,A=null,C=null}}};var F=(V)=>{if(typeof V==="string"&&V.trim())return V;if(V instanceof Error&&V.message.trim())return V.message;if(V&&typeof V==="object"){let g=V;for(let C of["message","reason","description"]){let A=g[C];if(typeof A==="string"&&A.trim())return A}if("error"in g)return F(g.error);if("cause"in g)return F(g.cause);try{return JSON.stringify(V)}catch{}}return"Unexpected error"},i=(V)=>{switch(V.type){case"audio":return{chunk:Uint8Array.from(atob(V.chunkBase64),(g)=>g.charCodeAt(0)),format:V.format,receivedAt:V.receivedAt,turnId:V.turnId,type:"audio"};case"assistant":return{text:V.text,turnId:V.turnId,type:"assistant"};case"assistant_delta":return{delta:V.delta,turnId:V.turnId,type:"assistant_delta"};case"complete":return{sessionId:V.sessionId,type:"complete"};case"connection":return{reconnect:V.reconnect,type:"connection"};case"call_lifecycle":return{event:V.event,sessionId:V.sessionId,type:"call_lifecycle"};case"error":return{message:F(V.message),recoverable:V.recoverable,type:"error"};case"call_control_ack":return null;case"final":return{transcript:V.transcript,type:"final"};case"partial":return{transcript:V.transcript,type:"partial"};case"replay":return{assistantTexts:V.assistantTexts,call:V.call,partial:V.partial,scenarioId:V.scenarioId,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,status:V.status,turns:V.turns,type:"replay"};case"session":return{sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,type:"session"};case"turn":return{turn:V.turn,type:"turn"};default:return null}};var UV=Math.PI*2;var N=(V,g,C,A)=>{V.push({code:C,message:A,severity:g})};var P0=(V)=>V.length===0?void 0:V.reduce((g,C)=>g+C,0)/V.length,x=(V)=>V.length===0?void 0:Math.max(...V);var K=(V,g)=>{let C=V[g];return typeof C==="number"&&Number.isFinite(C)?C:void 0},j=(V,g)=>{let C=V[g];return typeof C==="boolean"?C:void 0},E=(V,g)=>{let C=V[g];return typeof C==="string"?C:void 0},f=(V)=>String(V.id??E(V,"ssrc")??K(V,"ssrc")??E(V,"trackIdentifier")??E(V,"mid")??"unknown"),o=(V)=>V===void 0?void 0:V*1000;var B0=(V)=>{let g={};for(let[C,A]of Object.entries(V))if(A===null||typeof A==="boolean"||typeof A==="number"||typeof A==="string")g[C]=A;return g};var n=(V={})=>{let g=V.stats??[],C=[],A=g.filter(($)=>$.type==="inbound-rtp"&&E($,"kind")!=="video"),R=g.filter(($)=>$.type==="outbound-rtp"&&E($,"kind")!=="video"),_=g.filter(($)=>$.type==="candidate-pair"),D=g.filter(($)=>($.type==="track"||$.type==="media-source")&&E($,"kind")==="audio"),X=_.filter(($)=>j($,"selected")===!0||j($,"nominated")===!0||E($,"state")==="succeeded").length,H=D.filter(($)=>E($,"readyState")!=="ended"&&E($,"trackState")!=="ended"&&j($,"ended")!==!0).length,O=D.filter(($)=>E($,"readyState")==="ended"||E($,"trackState")==="ended"||j($,"ended")===!0).length,L=A.reduce(($,S)=>$+(K(S,"packetsReceived")??0),0),W=R.reduce(($,S)=>$+(K(S,"packetsSent")??0),0),U=[...A,...R].reduce(($,S)=>$+Math.max(0,K(S,"packetsLost")??0),0),T=L+U,J=T===0?0:U/T,y=A.reduce(($,S)=>$+(K(S,"bytesReceived")??0),0),Z=R.reduce(($,S)=>$+(K(S,"bytesSent")??0),0),Q=x(_.map(($)=>o(K($,"currentRoundTripTime")??K($,"roundTripTime"))).filter(($)=>$!==void 0)),G=x([...A,...R].map(($)=>o(K($,"jitter"))).filter(($)=>$!==void 0)),c=x(A.map(($)=>{let S=K($,"jitterBufferDelay"),b=K($,"jitterBufferEmittedCount");return S!==void 0&&b!==void 0&&b>0?S/b*1000:void 0}).filter(($)=>$!==void 0)),q=D.map(($)=>K($,"audioLevel")).filter(($)=>$!==void 0);if(V.requireConnectedCandidatePair&&_.length>0&&X===0)N(C,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(V.requireLiveAudioTrack&&H===0)N(C,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(V.maxPacketLossRatio!==void 0&&J>V.maxPacketLossRatio)N(C,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(J)} above ${String(V.maxPacketLossRatio)}.`);if(V.maxRoundTripTimeMs!==void 0&&Q!==void 0&&Q>V.maxRoundTripTimeMs)N(C,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(Q)}ms above ${String(V.maxRoundTripTimeMs)}ms.`);if(V.maxJitterMs!==void 0&&G!==void 0&&G>V.maxJitterMs)N(C,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(G)}ms above ${String(V.maxJitterMs)}ms.`);return{activeCandidatePairs:X,audioLevelAverage:P0(q),bytesReceived:y,bytesSent:Z,checkedAt:Date.now(),endedAudioTracks:O,inboundPackets:L,issues:C,jitterBufferDelayMs:c,jitterMs:G,liveAudioTracks:H,outboundPackets:W,packetLossRatio:J,packetsLost:U,roundTripTimeMs:Q,status:C.some(($)=>$.severity==="error")?"fail":C.length>0?"warn":"pass",totalStats:g.length}},m=async(V)=>{return[...(await V.peerConnection.getStats(V.selector??null)).values()].map(B0)};var u=(V={})=>{let g=V.stats??[],C=V.previousStats??[],A=[],R=new Map(C.map((U)=>[f(U),U])),D=g.filter((U)=>(U.type==="inbound-rtp"||U.type==="outbound-rtp")&&E(U,"kind")!=="video"&&E(U,"mediaType")!=="video").map((U)=>{let T=U.type==="outbound-rtp"?"outbound":"inbound",J=T==="outbound"?"packetsSent":"packetsReceived",y=T==="outbound"?"bytesSent":"bytesReceived",Z=R.get(f(U)),Q=K(U,J),G=Z?K(Z,J):void 0,c=K(U,y),q=Z?K(Z,y):void 0,$=U.timestamp!==void 0&&Z?.timestamp!==void 0?U.timestamp-Z.timestamp:void 0;return{bytesDelta:c!==void 0&&q!==void 0?c-q:void 0,currentPackets:Q,direction:T,id:f(U),packetDelta:Q!==void 0&&G!==void 0?Q-G:void 0,previousPackets:G,timeDeltaMs:$}}),X=D.filter((U)=>U.direction==="inbound"),H=D.filter((U)=>U.direction==="outbound"),O=x(D.map((U)=>U.timeDeltaMs).filter((U)=>U!==void 0)),L=X.filter((U)=>V.maxInboundPacketStallMs!==void 0&&U.timeDeltaMs!==void 0&&U.timeDeltaMs>=V.maxInboundPacketStallMs&&U.packetDelta!==void 0&&U.packetDelta<=0).length,W=H.filter((U)=>V.maxOutboundPacketStallMs!==void 0&&U.timeDeltaMs!==void 0&&U.timeDeltaMs>=V.maxOutboundPacketStallMs&&U.packetDelta!==void 0&&U.packetDelta<=0).length;if(V.requireInboundAudio&&X.length===0)N(A,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(V.requireOutboundAudio&&H.length===0)N(A,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(V.maxGapMs!==void 0&&O!==void 0&&O>V.maxGapMs)N(A,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(O)}ms above ${String(V.maxGapMs)}ms.`);if(L>0)N(A,"error","media.webrtc_inbound_stalled",`${String(L)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(W>0)N(A,"error","media.webrtc_outbound_stalled",`${String(W)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:X.length,issues:A,maxObservedGapMs:O,outboundAudioStreams:H.length,stalledInboundStreams:L,stalledOutboundStreams:W,status:A.some((U)=>U.severity==="error")?"fail":A.length>0?"warn":"pass",streams:D,totalStats:g.length}};var M0="/api/voice/browser-media",b0=5000,j0=async(V)=>V.peerConnection??await V.getPeerConnection?.()??null,x0=async(V,g)=>{let C=g.fetch??globalThis.fetch;if(!C)return;await C(g.path??M0,{body:JSON.stringify(V),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},r=(V)=>{let g=null,C=[],A=async()=>{let D=await j0(V);if(!D)return;let X=await m({peerConnection:D}),H=n({...V,stats:X}),O=V.continuity===!1?void 0:u({...V.continuity,previousStats:C,stats:X}),L={at:Date.now(),continuity:O,report:H,scenarioId:V.getScenarioId?.()??null,sessionId:V.getSessionId?.()??null};return C=X,V.onReport?.(L),await x0(L,V),L},R=()=>{A().catch((D)=>{V.onError?.(D)})},_=()=>{if(g)clearInterval(g),g=null};return{close:_,reportOnce:A,stop:_,start:()=>{if(g)return;R(),g=setInterval(R,V.intervalMs??b0)}}};var k0=(V,g,C)=>Math.min(C,g*2**(Math.max(1,V)-1));class s extends Error{constructor(V="Voice authorization could not be renewed."){super(V);this.name="VoiceReconnectRejectedError"}}var P=()=>{},F0=()=>Promise.resolve(),f0=()=>P,l0={callControl:F0,close:P,disconnect:P,endTurn:P,send:P,sendAudio:P,simulateDisconnect:P,subscribe:f0,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",start:()=>{}},d0=()=>crypto.randomUUID(),v0=(V,g,C,A)=>{let{hostname:R,port:_,protocol:D}=window.location,X=D==="https:"?"wss:":"ws:",H=_?`:${_}`:"",O=new URL(`${X}//${R}${H}${V}`);if(O.searchParams.set("sessionId",g),C)O.searchParams.set("scenarioId",C);for(let[L,W]of Object.entries(A))if(L!=="sessionId"&&L!=="scenarioId"&&W)O.searchParams.set(L,W);return O.toString()},i0=(V)=>{if(!V||typeof V!=="object"||!("type"in V))return!1;switch(V.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}},o0=(V)=>{if(typeof V.data!=="string")return null;try{let g=JSON.parse(V.data);return i0(g)?g:null}catch{return null}},a=(V,g={})=>{if(typeof window>"u")return l0;let C=new Set,A=new Map,R=g.reconnect!==!1,_=g.maxReconnectAttempts??15,D=g.reconnectMaxDelayMs??8000,X=g.pingInterval??30000,H=g.reconnectResetAfterMs??30000,O=0,L=!1,W=null,U=(I)=>k0(I,500,D),T={isConnected:!1,pendingMessages:[],scenarioId:g.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectResetTimeout:null,reconnectTimeout:null,sessionId:g.sessionId??d0(),ws:null},J=(I)=>{C.forEach((w)=>w(I))},y=(I)=>{C.forEach((w)=>w({message:I,recoverable:!1,type:"error"})),J({reconnect:{attempts:T.reconnectAttempts,maxAttempts:_,status:"exhausted"},type:"connection"})},Z=()=>{if(T.pingInterval)clearInterval(T.pingInterval),T.pingInterval=null;if(T.reconnectTimeout)clearTimeout(T.reconnectTimeout),T.reconnectTimeout=null;if(T.reconnectResetTimeout)clearTimeout(T.reconnectResetTimeout),T.reconnectResetTimeout=null},Q=()=>{if(T.ws?.readyState!==1)return;while(T.pendingMessages.length>0){let I=T.pendingMessages.shift();if(I!==void 0)T.ws.send(I)}},G=(I)=>{for(let w of A.values())clearTimeout(w.timeout),w.reject(Error(I));A.clear()},c=()=>{if(L)return;let I=O;T.reconnectAttempts+=1;let w=U(T.reconnectAttempts),h=Date.now()+w;J({reconnect:{attempts:T.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:_,nextAttemptAt:h,status:"reconnecting"},type:"connection"}),T.reconnectTimeout=setTimeout(async()=>{if(L||O!==I)return;if(T.reconnectAttempts>_){y("Voice connection could not be restored.");return}try{if(g.prepareReconnect){let Y=new AbortController;W=Y;let B=setTimeout(()=>Y.abort("Voice reconnect preparation timed out"),g.prepareReconnectTimeoutMs??1e4);try{await Promise.race([g.prepareReconnect({attempt:T.reconnectAttempts,path:V,scenarioId:T.scenarioId,sessionId:T.sessionId,signal:Y.signal}),new Promise((M,O0)=>{Y.signal.addEventListener("abort",()=>O0(Error("Voice reconnect preparation timed out.")),{once:!0})})])}finally{if(clearTimeout(B),W===Y)W=null}}}catch(Y){if(L||O!==I)return;if(Y instanceof s){y(Y.message);return}if(T.reconnectAttempts<_)c();else y("Voice authorization could not be renewed for reconnect.");return}if(L||O!==I)return;q()},w)},q=()=>{if(L)return;let I=new WebSocket(v0(V,T.sessionId,T.scenarioId,g.query??{}));I.binaryType="arraybuffer",I.onopen=()=>{if(T.ws!==I){I.close(1000);return}let w=T.reconnectAttempts>0;if(T.isConnected=!0,Q(),w)J({reconnect:{attempts:T.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:_,status:"resumed"},type:"connection"}),T.reconnectResetTimeout=setTimeout(()=>{if(T.ws===I&&I.readyState===1)T.reconnectAttempts=0;T.reconnectResetTimeout=null},H);T.pingInterval=setInterval(()=>{if(I.readyState===1)I.send(JSON.stringify({type:"ping"}))},X)},I.onmessage=(w)=>{if(T.ws!==I)return;let h=o0(w);if(!h)return;if(h.type==="session")T.sessionId=h.sessionId,T.scenarioId=h.scenarioId??T.scenarioId;if(h.type==="call_control_ack"){let Y=A.get(h.requestId);if(Y)if(clearTimeout(Y.timeout),A.delete(h.requestId),h.ok)Y.resolve();else Y.reject(Error(h.message??`${h.action} was not applied`))}C.forEach((Y)=>Y(h))},I.onclose=(w)=>{if(T.ws!==I)return;T.ws=null,T.isConnected=!1,Z(),G("Voice connection interrupted");let h=R&&w.code!==1000&&w.code!==4401&&w.code!==4403&&w.code!==4500&&T.reconnectAttempts<_,Y=w.code===4401||w.code===4403,B=w.code===4500;if(Y)C.forEach((M)=>M({message:w.code===4401?"Voice authorization expired or was rejected.":"Voice authorization was forbidden.",recoverable:!1,type:"error"}));if(B)C.forEach((M)=>M({message:"Voice provider initialization failed.",recoverable:!1,type:"error"}));if(h)c();else if(R&&w.code!==1000){if(Y)J({reconnect:{attempts:T.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:_,status:"exhausted"},type:"connection"});else if(!B)y("Voice connection could not be restored.")}},T.ws=I},$=(I)=>{if(L)return;if(T.ws?.readyState===1){T.ws.send(I);return}if(typeof I!=="string")return;if(T.pendingMessages.length>=100)T.pendingMessages.shift();T.pendingMessages.push(I)},S=(I)=>{$(JSON.stringify(I))},b=(I={})=>{if(I.sessionId&&I.sessionId!==T.sessionId)throw Error("Voice session switching requires a new connection instance.");if(I.sessionId)T.sessionId=I.sessionId;if(I.scenarioId)T.scenarioId=I.scenarioId;S({scenarioId:T.scenarioId??void 0,sessionId:T.sessionId,type:"start"})},I0=(I)=>{$(I)},U0=()=>{S({type:"end_turn"})},L0=(I)=>{if(T.ws?.readyState!==1)return Promise.reject(Error(`${I.action} is unavailable while disconnected`));let w=crypto.randomUUID(),{promise:h,reject:Y,resolve:B}=Promise.withResolvers(),M=setTimeout(()=>{A.delete(w),Y(Error(`${I.action} acknowledgement timed out`))},5000);return A.set(w,{reject:Y,resolve:B,timeout:M}),T.ws.send(JSON.stringify({...I,requestId:w,type:"call_control"})),h},W0=(I="client-close")=>{if(L=!0,W?.abort(),W=null,O+=1,Z(),G("Voice connection closed"),T.pendingMessages.length=0,T.ws){let w=T.ws;if(T.ws=null,w.readyState===1)w.send(JSON.stringify({reason:I,type:"close"}));w.close(1000)}T.isConnected=!1,C.clear()},D0=()=>{if(L=!0,W?.abort(),W=null,O+=1,Z(),G("Voice connection disconnected"),T.pendingMessages.length=0,T.ws){let I=T.ws;T.ws=null,I.close(1000)}T.isConnected=!1,C.clear()},X0=()=>{if(T.ws?.readyState===1)T.ws.close(4000,"absolutejs-voice-reconnect-proof")},G0=(I)=>{return C.add(I),()=>{C.delete(I)}};return q(),{callControl:L0,close:W0,disconnect:D0,endTurn:U0,send:S,sendAudio:I0,simulateDisconnect:X0,start:b,subscribe:G0,getReadyState:()=>T.ws?.readyState??3,getScenarioId:()=>T.scenarioId??"",getSessionId:()=>T.sessionId}};var n0=()=>({attempts:0,maxAttempts:0,status:"idle"}),m0=(V,g)=>{let C=g.trim().replace(/\s+/g," ");if(!C)return V;if(!V)return C;if(V===C||V.endsWith(C))return V;if(C.includes(V))return C;return`${V} ${C}`},u0=(V,g)=>{let C=g.trim().replace(/\s+/g," ");if(!V)return C;if(!C||V.endsWith(C))return V;return`${V} ${C}`},r0=()=>({assistantAudio:[],assistantStreamingText:"",assistantTexts:[],call:null,error:null,isConnected:!1,partial:"",reconnect:n0(),scenarioId:null,sessionId:null,sessionMetadata:null,status:"idle",turns:[]}),p=()=>{let V=r0(),g="",C=new Set,A=()=>{C.forEach((_)=>_())};return{dispatch:(_)=>{switch(_.type){case"audio":V={...V,assistantAudio:[...V.assistantAudio,{chunk:_.chunk,format:_.format,receivedAt:_.receivedAt,turnId:_.turnId}]};break;case"assistant":V={...V,assistantStreamingText:"",assistantTexts:[...V.assistantTexts,_.text]};break;case"assistant_delta":V={...V,assistantStreamingText:`${V.assistantStreamingText}${_.delta}`};break;case"complete":V={...V,sessionId:_.sessionId,status:"completed"};break;case"call_lifecycle":V={...V,call:{...V.call,disposition:_.event.type==="end"?_.event.disposition:V.call?.disposition,endedAt:_.event.type==="end"?_.event.at:V.call?.endedAt,events:[...V.call?.events??[],_.event],lastEventAt:_.event.at,startedAt:V.call?.startedAt??_.event.at},sessionId:_.sessionId};break;case"connected":V={...V,isConnected:!0,reconnect:V.reconnect.status==="reconnecting"?{...V.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:V.reconnect};break;case"connection":V={...V,reconnect:_.reconnect};break;case"disconnected":V={...V,isConnected:!1};break;case"error":V={...V,error:_.message,..._.recoverable===!1?{isConnected:!1,status:"failed"}:{}};break;case"final":g=m0(g,_.transcript.text),V={...V,partial:g};break;case"partial":V={...V,partial:u0(g,_.transcript.text)};break;case"replay":g=_.partial,V={...V,assistantStreamingText:"",assistantTexts:[..._.assistantTexts],call:_.call??null,error:null,isConnected:_.status==="active",partial:_.partial,reconnect:V.reconnect.status==="reconnecting"?{...V.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:V.reconnect,scenarioId:_.scenarioId??V.scenarioId,sessionId:_.sessionId,sessionMetadata:_.sessionMetadata??V.sessionMetadata,status:_.status,turns:[..._.turns]};break;case"session":V={...V,error:null,scenarioId:_.scenarioId??V.scenarioId,isConnected:_.status==="active",sessionId:_.sessionId,sessionMetadata:_.sessionMetadata??V.sessionMetadata,status:_.status};break;case"turn":g="",V={...V,partial:"",turns:[...V.turns,_.turn]};break}A()},getServerSnapshot:()=>V,getSnapshot:()=>V,subscribe:(_)=>{return C.add(_),()=>{C.delete(_)}}}};var t=(V,g={})=>{let C=a(V,g),A=p(),R=g.browserMedia&&typeof window<"u"?r({...g.browserMedia,getScenarioId:()=>g.browserMedia?g.browserMedia.getScenarioId?.()??C.getScenarioId():C.getScenarioId(),getSessionId:()=>g.browserMedia?g.browserMedia.getSessionId?.()??C.getSessionId():C.getSessionId()}):null,_=new Set,D=!1,X=(W)=>Promise.resolve().then(()=>{if(D)return;if(!W?.sessionId&&!W?.scenarioId)return;C.start(W),R?.start()}),H=()=>{_.forEach((W)=>W())},O=()=>{if(!g.reconnectReportPath||typeof fetch>"u")return;let W=A.getSnapshot(),U=JSON.stringify({at:Date.now(),reconnect:W.reconnect,scenarioId:W.scenarioId,sessionId:C.getSessionId(),turnIds:W.turns.map((T)=>T.id)});fetch(g.reconnectReportPath,{body:U,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},L=C.subscribe((W)=>{let U=i(W);if(U){if(A.dispatch(U),W.type==="connection")O();H()}});return{start:X,get assistantAudio(){return A.getSnapshot().assistantAudio},get assistantTexts(){return A.getSnapshot().assistantTexts},get assistantStreamingText(){return A.getSnapshot().assistantStreamingText},get call(){return A.getSnapshot().call},callControl(W){return C.callControl(W)},close(W){D=!0,L(),R?.close(),C.close(W),A.dispatch({type:"disconnected"}),H()},disconnect(){D=!0,L(),R?.close(),C.disconnect(),A.dispatch({type:"disconnected"}),H()},endTurn(){C.endTurn()},get error(){return A.getSnapshot().error},getServerSnapshot(){return A.getServerSnapshot()},getSnapshot(){return A.getSnapshot()},get isConnected(){return A.getSnapshot().isConnected},get partial(){return A.getSnapshot().partial},get reconnect(){return A.getSnapshot().reconnect},get scenarioId(){return A.getSnapshot().scenarioId},sendAudio(W){C.sendAudio(W)},get sessionId(){return C.getSessionId()},get sessionMetadata(){return A.getSnapshot().sessionMetadata},simulateDisconnect(){C.simulateDisconnect()},get status(){return A.getSnapshot().status},subscribe(W){return _.add(W),()=>{_.delete(W)}},get turns(){return A.getSnapshot().turns}}};var e=(V)=>{if(!V||V.enabled===!1)return;return{enabled:!0,maxGain:V.maxGain??3,noiseGateAttenuation:V.noiseGateAttenuation??0.15,noiseGateThreshold:V.noiseGateThreshold??0.006,targetLevel:V.targetLevel??0.08}};var s0={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}},a0={"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 V0=(V)=>{let g=V?.profile??"fast",C=V?.qualityProfile??"general",A=s0[g],R=a0[C],_=V?.silenceMs??R.silenceMs??A.silenceMs;return{profile:g,qualityProfile:C,minSilenceMs:Math.min(_,V?.minSilenceMs??R.minSilenceMs??A.minSilenceMs),silenceMs:_,speechThreshold:V?.speechThreshold??R.speechThreshold??A.speechThreshold,transcriptStabilityMs:V?.transcriptStabilityMs??R.transcriptStabilityMs??A.transcriptStabilityMs}};var p0={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"}}},g0=(V="default")=>{let g=p0[V];return{audioConditioning:e(g.audioConditioning),capture:{channelCount:g.capture?.channelCount??1,sampleRateHz:g.capture?.sampleRateHz??16000},connection:{...g.connection},name:V,sttLifecycle:g.sttLifecycle??"continuous",turnDetection:V0(g.turnDetection)}};var t0=(V)=>({assistantAudio:[...V.assistantAudio],assistantStreamingText:V.assistantStreamingText,assistantTexts:[...V.assistantTexts],call:V.call,error:V.error,isConnected:V.isConnected,isRecording:!1,partial:V.partial,reconnect:V.reconnect,recordingError:null,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,turns:[...V.turns]}),A0=(V,g={})=>{let C=g0(g.preset),A=t(V,{...C.connection,...g.connection}),R=null,_=0,D=!1,X=null,H=t0(A),O=new Set,L=()=>{for(let G of O)G()},W=()=>{if(H={...H,assistantAudio:[...A.assistantAudio],assistantStreamingText:A.assistantStreamingText,assistantTexts:[...A.assistantTexts],call:A.call,error:A.error,isConnected:A.isConnected,partial:A.partial,reconnect:A.reconnect,sessionId:A.sessionId,sessionMetadata:A.sessionMetadata,scenarioId:A.scenarioId,status:A.status,turns:[...A.turns]},g.autoStopOnComplete!==!1&&H.status==="completed"&&H.isRecording)R?.stop(),R=null,H={...H,isRecording:!1};L()},U=A.subscribe(W);W();let T=()=>{if(R)return R;return R=v({channelCount:g.capture?.channelCount??C.capture.channelCount,onLevel:g.capture?.onLevel,onAudio:(G)=>{if(g.capture?.onAudio){g.capture.onAudio(G,A.sendAudio);return}A.sendAudio(G)},sampleRateHz:g.capture?.sampleRateHz??C.capture.sampleRateHz,...g.capture?.stream?{stream:g.capture.stream}:{}}),R},J=()=>{_+=1,R?.stop(),R=null,H={...H,isRecording:!1},L()},y=async()=>{if(D)throw Error("Voice controller is closed.");if(H.isRecording)return;if(X)return X;let G=++_,c=T(),$=(async()=>{try{if(H={...H,recordingError:null},L(),await c.start(),D||G!==_||R!==c){c.stop();return}H={...H,isRecording:!0},L()}catch(S){if(c.stop(),G!==_||R!==c)throw S;throw R=null,H={...H,isRecording:!1,recordingError:S instanceof Error?S.message:String(S)},L(),S}})().finally(()=>{if(X===$)X=null});return X=$,X};return{close:(G)=>{D=!0,U(),J(),A.close(G)},disconnect:()=>{D=!0,U(),J(),A.disconnect()},startRecording:y,stopRecording:J,get assistantAudio(){return H.assistantAudio},get assistantTexts(){return H.assistantTexts},get assistantStreamingText(){return H.assistantStreamingText},bindHTMX(G){return d(A,G)},get call(){return H.call},callControl:(G)=>A.callControl(G),endTurn:()=>A.endTurn(),get error(){return H.error},getServerSnapshot:()=>H,getSnapshot:()=>H,get isConnected(){return H.isConnected},get isRecording(){return H.isRecording},get partial(){return H.partial},get reconnect(){return H.reconnect},get recordingError(){return H.recordingError},get scenarioId(){return H.scenarioId},sendAudio:(G)=>A.sendAudio(G),get sessionId(){return H.sessionId},get sessionMetadata(){return H.sessionMetadata},simulateDisconnect:()=>A.simulateDisconnect(),get status(){return H.status},subscribe:(G)=>{return O.add(G),()=>{O.delete(G)}},toggleRecording:async()=>{if(H.isRecording){J();return}await y()},get turns(){return H.turns}}};var z=(V)=>String(V).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;");var C0=(V)=>{if(!V.isConnected)return"idle";if(V.isPlaying)return"speaking";if(V.isRecording&&V.hasActivePartial)return"listening";if(V.isRecording)return"listening";if(V.lastTranscriptAt&&!V.lastAssistantAt)return"thinking";if(V.lastTranscriptAt&&V.lastAssistantAt&&V.lastTranscriptAt>V.lastAssistantAt)return"thinking";return"idle"};var e0={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},VV={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},gV=(V,g)=>{switch(V){case"listening":return g.listening;case"speaking":return g.speaking;case"thinking":return g.thinking;case"idle":return g.idle}},_0=(V)=>{let g={...e0,...V.theme},C={...VV,...V.labels},A=V.state.assistantAudio.at(-1)?.receivedAt,R=V.state.turns.at(-1)?.committedAt,_=C0({hasActivePartial:V.state.partial.length>0,isConnected:V.state.isConnected,isPlaying:!1,isRecording:V.state.isRecording,lastAssistantAt:A,lastTranscriptAt:R}),D=!V.state.isConnected&&V.state.status!=="idle"&&!V.state.error,X=V.state.error?"Error":D?C.connecting:V.state.status==="completed"?C.callEnded:gV(_,C);return{agentState:_,classes:{container:`absolute-voice-widget absolute-voice-widget--${_}`,dot:`absolute-voice-widget__dot${V.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:V.state.isConnected,canMute:V.state.isRecording,canStart:!V.state.isRecording&&V.state.status!=="completed"},errorMessage:V.state.error??void 0,labels:C,partial:V.state.partial||void 0,statusLabel:X,theme:g,title:V.title??"Voice"}},AV=(V)=>typeof V==="number"?`${V}px`:V,T0=(V)=>{let g=V.theme,C=`background:${g.background};border-radius:${AV(g.radius)};color:${g.foreground};font-family:${g.fontFamily};min-width:240px;padding:20px 22px;`,A=`background:${V.errorMessage?g.errorAccent:V.agentState==="idle"?"rgba(148,163,184,0.6)":g.accent};border-radius:50%;height:10px;width:10px;`,R=[];if(V.controls.canStart)R.push(`<button type="button" data-action="start" style="background:${g.accent};border:none;border-radius:12px;color:${g.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${z(V.labels.startCall)}</button>`);if(V.controls.canMute)R.push(`<button type="button" data-action="mute" style="background:transparent;border:1px solid rgba(255,255,255,0.18);border-radius:12px;color:${g.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${z(V.labels.mute)}</button>`);if(V.controls.canEnd)R.push(`<button type="button" data-action="end" style="background:${g.errorAccent};border:none;border-radius:12px;color:${g.foreground};cursor:pointer;font-size:14px;font-weight:500;padding:10px 14px;">${z(V.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${V.agentState}" class="${z(V.classes.container)}" style="${C}">
1
+ (()=>{var{defineProperty:k,getOwnPropertyNames:S0,getOwnPropertyDescriptor:w0}=Object,J0=Object.prototype.hasOwnProperty;function h0(V){return this[V]}var Y0=(V)=>{var A=(l??=new WeakMap).get(V),C;if(A)return A;if(A=k({},"__esModule",{value:!0}),V&&typeof V==="object"||typeof V==="function"){for(var g of S0(V))if(!J0.call(A,g))k(A,g,{get:h0.bind(V,g),enumerable:!(C=w0(V,g))||C.enumerable})}return l.set(V,A),A},l;var Z0=(V)=>V;function y0(V,A){this[V]=Z0.bind(null,A)}var Q0=(V,A)=>{for(var C in A)k(V,C,{get:A[C],enumerable:!0,configurable:!0,set:y0.bind(A,C)})};var _V={};Q0(_V,{mount:()=>$0,default:()=>TV,VOICE_EMBED_VERSION:()=>R0});var E0=(V)=>{if(typeof V!=="string")return V;return document.querySelector(V)},K0=(V,A,C,g)=>{let H=A??V.getAttribute("hx-get")??"";if(!H)return"";let _=new URL(H,window.location.origin);if(g)_.searchParams.set(C,g);else _.searchParams.delete(C);return`${_.pathname}${_.search}${_.hash}`},d=(V,A)=>{if(typeof window>"u"||typeof document>"u")return()=>{};let C=E0(A.element);if(!C)return()=>{};let g=A.eventName??"voice-refresh",H=A.sessionQueryParam??"sessionId",_=()=>{let X=window,R=K0(C,A.route,H,V.sessionId);if(R)C.setAttribute("hx-get",R);X.htmx?.process?.(C),X.htmx?.trigger?.(C,g)},D=V.subscribe(_);return _(),()=>{D()}};var c0=(V)=>Math.max(-1,Math.min(1,V)),q0=(V)=>{let A=new Int16Array(V.length);for(let C=0;C<V.length;C+=1){let g=c0(V[C]??0);A[C]=g<0?g*32768:g*32767}return new Uint8Array(A.buffer)},N0=(V)=>{let A=V instanceof Uint8Array?V:new Uint8Array(V);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 g=0;for(let H of C){let _=H/32768;g+=_*_}return Math.min(1,Math.max(0,Math.sqrt(g/C.length)*5.5))},z0=(V,A,C)=>{if(A===C)return V;let g=A/C,H=Math.round(V.length/g),_=new Float32Array(H),D=0,X=0;while(D<_.length){let R=Math.round((D+1)*g),O=0,L=0;for(let W=X;W<R&&W<V.length;W+=1)O+=V[W]??0,L+=1;_[D]=L>0?O/L:0,D+=1,X=R}return _},v=(V)=>{let A=null,C=null,g=null,H=null,_=0,D=null,X=(L)=>{L.processorNode?.disconnect(),L.sourceNode?.disconnect(),L.mediaStream?.getTracks().forEach((W)=>W.stop()),L.audioContext?.close()};return{start:()=>{if(H)return Promise.resolve();if(D)return D;let L=++_,U=(async()=>{if(!V.stream&&(typeof navigator>"u"||!navigator.mediaDevices?.getUserMedia))throw Error("Browser microphone capture requires navigator.mediaDevices.getUserMedia.");let T=(typeof window<"u"?window.AudioContext??window.webkitAudioContext:void 0)??AudioContext;if(!T)throw Error("Browser microphone capture requires AudioContext support.");let w=null,Z=null,Y=null,Q=null;try{if(Z=V.stream??await navigator.mediaDevices.getUserMedia({audio:{autoGainControl:!0,channelCount:V.channelCount??1,echoCancellation:!0,noiseSuppression:!0}}),L!==_)throw Error("Microphone capture stopped during startup.");if(w=new T,w.state==="suspended")await w.resume();if(L!==_)throw Error("Microphone capture stopped during startup.");if(Q=w.createMediaStreamSource(Z),Y=w.createScriptProcessor(4096,1,1),Y.onaudioprocess=(G)=>{let K=G.inputBuffer.getChannelData(0),q=z0(K,w?.sampleRate??48000,V.sampleRateHz??16000),$=q0(q);V.onLevel?.(N0($)),V.onAudio($)},Q.connect(Y),Y.connect(w.destination),L!==_)throw Error("Microphone capture stopped during startup.");A=w,H=Z,g=Y,C=Q}catch(G){throw X({audioContext:w,mediaStream:Z,processorNode:Y,sourceNode:Q}),G}})().finally(()=>{if(D===U)D=null});return D=U,U},stop:()=>{_+=1,X({audioContext:A,mediaStream:H,processorNode:g,sourceNode:C}),V.onLevel?.(0),A=null,H=null,g=null,C=null}}};var F=(V)=>{if(typeof V==="string"&&V.trim())return V;if(V instanceof Error&&V.message.trim())return V.message;if(V&&typeof V==="object"){let A=V;for(let C of["message","reason","description"]){let g=A[C];if(typeof g==="string"&&g.trim())return g}if("error"in A)return F(A.error);if("cause"in A)return F(A.cause);try{return JSON.stringify(V)}catch{}}return"Unexpected error"},i=(V)=>{switch(V.type){case"audio":return{chunk:Uint8Array.from(atob(V.chunkBase64),(A)=>A.charCodeAt(0)),format:V.format,receivedAt:V.receivedAt,turnId:V.turnId,type:"audio"};case"assistant":return{text:V.text,turnId:V.turnId,type:"assistant"};case"assistant_delta":return{delta:V.delta,turnId:V.turnId,type:"assistant_delta"};case"complete":return{sessionId:V.sessionId,type:"complete"};case"connection":return{reconnect:V.reconnect,type:"connection"};case"call_lifecycle":return{event:V.event,sessionId:V.sessionId,type:"call_lifecycle"};case"error":return{message:F(V.message),recoverable:V.recoverable,type:"error"};case"call_control_ack":return null;case"final":return{transcript:V.transcript,type:"final"};case"partial":return{transcript:V.transcript,type:"partial"};case"replay":return{assistantTexts:V.assistantTexts,call:V.call,partial:V.partial,scenarioId:V.scenarioId,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,status:V.status,turns:V.turns,type:"replay"};case"session":return{paused:V.paused,pauseExpiresAt:V.pauseExpiresAt,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,type:"session"};case"turn":return{turn:V.turn,type:"turn"};default:return null}};var UV=Math.PI*2;var N=(V,A,C,g)=>{V.push({code:C,message:g,severity:A})};var P0=(V)=>V.length===0?void 0:V.reduce((A,C)=>A+C,0)/V.length,x=(V)=>V.length===0?void 0:Math.max(...V);var E=(V,A)=>{let C=V[A];return typeof C==="number"&&Number.isFinite(C)?C:void 0},j=(V,A)=>{let C=V[A];return typeof C==="boolean"?C:void 0},c=(V,A)=>{let C=V[A];return typeof C==="string"?C:void 0},f=(V)=>String(V.id??c(V,"ssrc")??E(V,"ssrc")??c(V,"trackIdentifier")??c(V,"mid")??"unknown"),o=(V)=>V===void 0?void 0:V*1000;var B0=(V)=>{let A={};for(let[C,g]of Object.entries(V))if(g===null||typeof g==="boolean"||typeof g==="number"||typeof g==="string")A[C]=g;return A};var n=(V={})=>{let A=V.stats??[],C=[],g=A.filter(($)=>$.type==="inbound-rtp"&&c($,"kind")!=="video"),H=A.filter(($)=>$.type==="outbound-rtp"&&c($,"kind")!=="video"),_=A.filter(($)=>$.type==="candidate-pair"),D=A.filter(($)=>($.type==="track"||$.type==="media-source")&&c($,"kind")==="audio"),X=_.filter(($)=>j($,"selected")===!0||j($,"nominated")===!0||c($,"state")==="succeeded").length,R=D.filter(($)=>c($,"readyState")!=="ended"&&c($,"trackState")!=="ended"&&j($,"ended")!==!0).length,O=D.filter(($)=>c($,"readyState")==="ended"||c($,"trackState")==="ended"||j($,"ended")===!0).length,L=g.reduce(($,J)=>$+(E(J,"packetsReceived")??0),0),W=H.reduce(($,J)=>$+(E(J,"packetsSent")??0),0),U=[...g,...H].reduce(($,J)=>$+Math.max(0,E(J,"packetsLost")??0),0),T=L+U,w=T===0?0:U/T,Z=g.reduce(($,J)=>$+(E(J,"bytesReceived")??0),0),Y=H.reduce(($,J)=>$+(E(J,"bytesSent")??0),0),Q=x(_.map(($)=>o(E($,"currentRoundTripTime")??E($,"roundTripTime"))).filter(($)=>$!==void 0)),G=x([...g,...H].map(($)=>o(E($,"jitter"))).filter(($)=>$!==void 0)),K=x(g.map(($)=>{let J=E($,"jitterBufferDelay"),b=E($,"jitterBufferEmittedCount");return J!==void 0&&b!==void 0&&b>0?J/b*1000:void 0}).filter(($)=>$!==void 0)),q=D.map(($)=>E($,"audioLevel")).filter(($)=>$!==void 0);if(V.requireConnectedCandidatePair&&_.length>0&&X===0)N(C,"error","media.webrtc_candidate_pair_missing","No active WebRTC candidate pair was observed.");if(V.requireLiveAudioTrack&&R===0)N(C,"error","media.webrtc_audio_track_missing","No live WebRTC audio track was observed.");if(V.maxPacketLossRatio!==void 0&&w>V.maxPacketLossRatio)N(C,"warning","media.webrtc_packet_loss",`Observed WebRTC packet loss ratio ${String(w)} above ${String(V.maxPacketLossRatio)}.`);if(V.maxRoundTripTimeMs!==void 0&&Q!==void 0&&Q>V.maxRoundTripTimeMs)N(C,"warning","media.webrtc_round_trip_time",`Observed WebRTC RTT ${String(Q)}ms above ${String(V.maxRoundTripTimeMs)}ms.`);if(V.maxJitterMs!==void 0&&G!==void 0&&G>V.maxJitterMs)N(C,"warning","media.webrtc_jitter",`Observed WebRTC jitter ${String(G)}ms above ${String(V.maxJitterMs)}ms.`);return{activeCandidatePairs:X,audioLevelAverage:P0(q),bytesReceived:Z,bytesSent:Y,checkedAt:Date.now(),endedAudioTracks:O,inboundPackets:L,issues:C,jitterBufferDelayMs:K,jitterMs:G,liveAudioTracks:R,outboundPackets:W,packetLossRatio:w,packetsLost:U,roundTripTimeMs:Q,status:C.some(($)=>$.severity==="error")?"fail":C.length>0?"warn":"pass",totalStats:A.length}},m=async(V)=>{return[...(await V.peerConnection.getStats(V.selector??null)).values()].map(B0)};var u=(V={})=>{let A=V.stats??[],C=V.previousStats??[],g=[],H=new Map(C.map((U)=>[f(U),U])),D=A.filter((U)=>(U.type==="inbound-rtp"||U.type==="outbound-rtp")&&c(U,"kind")!=="video"&&c(U,"mediaType")!=="video").map((U)=>{let T=U.type==="outbound-rtp"?"outbound":"inbound",w=T==="outbound"?"packetsSent":"packetsReceived",Z=T==="outbound"?"bytesSent":"bytesReceived",Y=H.get(f(U)),Q=E(U,w),G=Y?E(Y,w):void 0,K=E(U,Z),q=Y?E(Y,Z):void 0,$=U.timestamp!==void 0&&Y?.timestamp!==void 0?U.timestamp-Y.timestamp:void 0;return{bytesDelta:K!==void 0&&q!==void 0?K-q:void 0,currentPackets:Q,direction:T,id:f(U),packetDelta:Q!==void 0&&G!==void 0?Q-G:void 0,previousPackets:G,timeDeltaMs:$}}),X=D.filter((U)=>U.direction==="inbound"),R=D.filter((U)=>U.direction==="outbound"),O=x(D.map((U)=>U.timeDeltaMs).filter((U)=>U!==void 0)),L=X.filter((U)=>V.maxInboundPacketStallMs!==void 0&&U.timeDeltaMs!==void 0&&U.timeDeltaMs>=V.maxInboundPacketStallMs&&U.packetDelta!==void 0&&U.packetDelta<=0).length,W=R.filter((U)=>V.maxOutboundPacketStallMs!==void 0&&U.timeDeltaMs!==void 0&&U.timeDeltaMs>=V.maxOutboundPacketStallMs&&U.packetDelta!==void 0&&U.packetDelta<=0).length;if(V.requireInboundAudio&&X.length===0)N(g,"error","media.webrtc_inbound_audio_missing","No inbound WebRTC audio RTP stream was observed.");if(V.requireOutboundAudio&&R.length===0)N(g,"error","media.webrtc_outbound_audio_missing","No outbound WebRTC audio RTP stream was observed.");if(V.maxGapMs!==void 0&&O!==void 0&&O>V.maxGapMs)N(g,"warning","media.webrtc_stream_gap",`Observed WebRTC stream sample gap ${String(O)}ms above ${String(V.maxGapMs)}ms.`);if(L>0)N(g,"error","media.webrtc_inbound_stalled",`${String(L)} inbound WebRTC audio stream(s) stopped receiving packets.`);if(W>0)N(g,"error","media.webrtc_outbound_stalled",`${String(W)} outbound WebRTC audio stream(s) stopped sending packets.`);return{checkedAt:Date.now(),inboundAudioStreams:X.length,issues:g,maxObservedGapMs:O,outboundAudioStreams:R.length,stalledInboundStreams:L,stalledOutboundStreams:W,status:g.some((U)=>U.severity==="error")?"fail":g.length>0?"warn":"pass",streams:D,totalStats:A.length}};var M0="/api/voice/browser-media",b0=5000,j0=async(V)=>V.peerConnection??await V.getPeerConnection?.()??null,x0=async(V,A)=>{let C=A.fetch??globalThis.fetch;if(!C)return;await C(A.path??M0,{body:JSON.stringify(V),headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"})},r=(V)=>{let A=null,C=[],g=async()=>{let D=await j0(V);if(!D)return;let X=await m({peerConnection:D}),R=n({...V,stats:X}),O=V.continuity===!1?void 0:u({...V.continuity,previousStats:C,stats:X}),L={at:Date.now(),continuity:O,report:R,scenarioId:V.getScenarioId?.()??null,sessionId:V.getSessionId?.()??null};return C=X,V.onReport?.(L),await x0(L,V),L},H=()=>{g().catch((D)=>{V.onError?.(D)})},_=()=>{if(A)clearInterval(A),A=null};return{close:_,reportOnce:g,stop:_,start:()=>{if(A)return;H(),A=setInterval(H,V.intervalMs??b0)}}};var k0=(V,A,C)=>Math.min(C,A*2**(Math.max(1,V)-1));class s extends Error{constructor(V="Voice authorization could not be renewed."){super(V);this.name="VoiceReconnectRejectedError"}}var P=()=>{},F0=()=>Promise.resolve(),f0=()=>P,l0={callControl:F0,close:P,disconnect:P,endTurn:P,send:P,sendAudio:P,simulateDisconnect:P,subscribe:f0,getReadyState:()=>3,getScenarioId:()=>"",getSessionId:()=>"",start:()=>{}},d0=()=>crypto.randomUUID(),v0=(V,A,C,g)=>{let{hostname:H,port:_,protocol:D}=window.location,X=D==="https:"?"wss:":"ws:",R=_?`:${_}`:"",O=new URL(`${X}//${H}${R}${V}`);if(O.searchParams.set("sessionId",A),C)O.searchParams.set("scenarioId",C);for(let[L,W]of Object.entries(g))if(L!=="sessionId"&&L!=="scenarioId"&&W)O.searchParams.set(L,W);return O.toString()},i0=(V)=>{if(!V||typeof V!=="object"||!("type"in V))return!1;switch(V.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}},o0=(V)=>{if(typeof V.data!=="string")return null;try{let A=JSON.parse(V.data);return i0(A)?A:null}catch{return null}},a=(V,A={})=>{if(typeof window>"u")return l0;let C=new Set,g=new Map,H=A.reconnect!==!1,_=A.maxReconnectAttempts??15,D=A.reconnectMaxDelayMs??8000,X=A.pingInterval??30000,R=A.reconnectResetAfterMs??30000,O=0,L=!1,W=null,U=(I)=>k0(I,500,D),T={isConnected:!1,pendingMessages:[],scenarioId:A.scenarioId??null,pingInterval:null,reconnectAttempts:0,reconnectResetTimeout:null,reconnectTimeout:null,sessionId:A.sessionId??d0(),ws:null},w=(I)=>{C.forEach((S)=>S(I))},Z=(I)=>{C.forEach((S)=>S({message:I,recoverable:!1,type:"error"})),w({reconnect:{attempts:T.reconnectAttempts,maxAttempts:_,status:"exhausted"},type:"connection"})},Y=()=>{if(T.pingInterval)clearInterval(T.pingInterval),T.pingInterval=null;if(T.reconnectTimeout)clearTimeout(T.reconnectTimeout),T.reconnectTimeout=null;if(T.reconnectResetTimeout)clearTimeout(T.reconnectResetTimeout),T.reconnectResetTimeout=null},Q=()=>{if(T.ws?.readyState!==1)return;while(T.pendingMessages.length>0){let I=T.pendingMessages.shift();if(I!==void 0)T.ws.send(I)}},G=(I)=>{for(let S of g.values())clearTimeout(S.timeout),S.reject(Error(I));g.clear()},K=()=>{if(L)return;let I=O;T.reconnectAttempts+=1;let S=U(T.reconnectAttempts),y=Date.now()+S;w({reconnect:{attempts:T.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:_,nextAttemptAt:y,status:"reconnecting"},type:"connection"}),T.reconnectTimeout=setTimeout(async()=>{if(L||O!==I)return;if(T.reconnectAttempts>_){Z("Voice connection could not be restored.");return}try{if(A.prepareReconnect){let h=new AbortController;W=h;let B=setTimeout(()=>h.abort("Voice reconnect preparation timed out"),A.prepareReconnectTimeoutMs??1e4);try{await Promise.race([A.prepareReconnect({attempt:T.reconnectAttempts,path:V,scenarioId:T.scenarioId,sessionId:T.sessionId,signal:h.signal}),new Promise((M,O0)=>{h.signal.addEventListener("abort",()=>O0(Error("Voice reconnect preparation timed out.")),{once:!0})})])}finally{if(clearTimeout(B),W===h)W=null}}}catch(h){if(L||O!==I)return;if(h instanceof s){Z(h.message);return}if(T.reconnectAttempts<_)K();else Z("Voice authorization could not be renewed for reconnect.");return}if(L||O!==I)return;q()},S)},q=()=>{if(L)return;let I=new WebSocket(v0(V,T.sessionId,T.scenarioId,A.query??{}));I.binaryType="arraybuffer",I.onopen=()=>{if(T.ws!==I){I.close(1000);return}let S=T.reconnectAttempts>0;if(T.isConnected=!0,Q(),S)w({reconnect:{attempts:T.reconnectAttempts,lastResumedAt:Date.now(),maxAttempts:_,status:"resumed"},type:"connection"}),T.reconnectResetTimeout=setTimeout(()=>{if(T.ws===I&&I.readyState===1)T.reconnectAttempts=0;T.reconnectResetTimeout=null},R);T.pingInterval=setInterval(()=>{if(I.readyState===1)I.send(JSON.stringify({type:"ping"}))},X)},I.onmessage=(S)=>{if(T.ws!==I)return;let y=o0(S);if(!y)return;if(y.type==="session")T.sessionId=y.sessionId,T.scenarioId=y.scenarioId??T.scenarioId;if(y.type==="call_control_ack"){let h=g.get(y.requestId);if(h)if(clearTimeout(h.timeout),g.delete(y.requestId),y.ok)h.resolve();else h.reject(Error(y.message??`${y.action} was not applied`))}C.forEach((h)=>h(y))},I.onclose=(S)=>{if(T.ws!==I)return;T.ws=null,T.isConnected=!1,Y(),G("Voice connection interrupted");let y=H&&S.code!==1000&&S.code!==4401&&S.code!==4403&&S.code!==4500&&T.reconnectAttempts<_,h=S.code===4401||S.code===4403,B=S.code===4500;if(h)C.forEach((M)=>M({message:S.code===4401?"Voice authorization expired or was rejected.":"Voice authorization was forbidden.",recoverable:!1,type:"error"}));if(B)C.forEach((M)=>M({message:"Voice provider initialization failed.",recoverable:!1,type:"error"}));if(y)K();else if(H&&S.code!==1000){if(h)w({reconnect:{attempts:T.reconnectAttempts,lastDisconnectAt:Date.now(),maxAttempts:_,status:"exhausted"},type:"connection"});else if(!B)Z("Voice connection could not be restored.")}},T.ws=I},$=(I)=>{if(L)return;if(T.ws?.readyState===1){T.ws.send(I);return}if(typeof I!=="string")return;if(T.pendingMessages.length>=100)T.pendingMessages.shift();T.pendingMessages.push(I)},J=(I)=>{$(JSON.stringify(I))},b=(I={})=>{if(I.sessionId&&I.sessionId!==T.sessionId)throw Error("Voice session switching requires a new connection instance.");if(I.sessionId)T.sessionId=I.sessionId;if(I.scenarioId)T.scenarioId=I.scenarioId;J({scenarioId:T.scenarioId??void 0,sessionId:T.sessionId,type:"start"})},I0=(I)=>{$(I)},U0=()=>{J({type:"end_turn"})},L0=(I)=>{if(T.ws?.readyState!==1)return Promise.reject(Error(`${I.action} is unavailable while disconnected`));let S=crypto.randomUUID(),{promise:y,reject:h,resolve:B}=Promise.withResolvers(),M=setTimeout(()=>{g.delete(S),h(Error(`${I.action} acknowledgement timed out`))},5000);return g.set(S,{reject:h,resolve:B,timeout:M}),T.ws.send(JSON.stringify({...I,requestId:S,type:"call_control"})),y},W0=(I="client-close")=>{if(L=!0,W?.abort(),W=null,O+=1,Y(),G("Voice connection closed"),T.pendingMessages.length=0,T.ws){let S=T.ws;if(T.ws=null,S.readyState===1)S.send(JSON.stringify({reason:I,type:"close"}));S.close(1000)}T.isConnected=!1,C.clear()},D0=()=>{if(L=!0,W?.abort(),W=null,O+=1,Y(),G("Voice connection disconnected"),T.pendingMessages.length=0,T.ws){let I=T.ws;T.ws=null,I.close(1000)}T.isConnected=!1,C.clear()},X0=()=>{if(T.ws?.readyState===1)T.ws.close(4000,"absolutejs-voice-reconnect-proof")},G0=(I)=>{return C.add(I),()=>{C.delete(I)}};return q(),{callControl:L0,close:W0,disconnect:D0,endTurn:U0,send:J,sendAudio:I0,simulateDisconnect:X0,start:b,subscribe:G0,getReadyState:()=>T.ws?.readyState??3,getScenarioId:()=>T.scenarioId??"",getSessionId:()=>T.sessionId}};var n0=()=>({attempts:0,maxAttempts:0,status:"idle"}),m0=(V,A)=>{let C=A.trim().replace(/\s+/g," ");if(!C)return V;if(!V)return C;if(V===C||V.endsWith(C))return V;if(C.includes(V))return C;return`${V} ${C}`},u0=(V,A)=>{let C=A.trim().replace(/\s+/g," ");if(!V)return C;if(!C||V.endsWith(C))return V;return`${V} ${C}`},r0=()=>({assistantAudio:[],assistantStreamingText:"",assistantTexts:[],call:null,error:null,isConnected:!1,paused:!1,partial:"",reconnect:n0(),scenarioId:null,sessionId:null,sessionMetadata:null,status:"idle",turns:[]}),p=()=>{let V=r0(),A="",C=new Set,g=()=>{C.forEach((_)=>_())};return{dispatch:(_)=>{switch(_.type){case"audio":V={...V,assistantAudio:[...V.assistantAudio,{chunk:_.chunk,format:_.format,receivedAt:_.receivedAt,turnId:_.turnId}]};break;case"assistant":V={...V,assistantStreamingText:"",assistantTexts:[...V.assistantTexts,_.text]};break;case"assistant_delta":V={...V,assistantStreamingText:`${V.assistantStreamingText}${_.delta}`};break;case"complete":V={...V,sessionId:_.sessionId,status:"completed"};break;case"call_lifecycle":V={...V,call:{...V.call,disposition:_.event.type==="end"?_.event.disposition:V.call?.disposition,endedAt:_.event.type==="end"?_.event.at:V.call?.endedAt,events:[...V.call?.events??[],_.event],lastEventAt:_.event.at,startedAt:V.call?.startedAt??_.event.at},sessionId:_.sessionId};break;case"connected":V={...V,isConnected:!0,reconnect:V.reconnect.status==="reconnecting"?{...V.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:V.reconnect};break;case"connection":V={...V,reconnect:_.reconnect};break;case"disconnected":V={...V,isConnected:!1};break;case"error":V={...V,error:_.message,..._.recoverable===!1?{isConnected:!1,status:"failed"}:{}};break;case"final":A=m0(A,_.transcript.text),V={...V,partial:A};break;case"partial":V={...V,partial:u0(A,_.transcript.text)};break;case"replay":A=_.partial,V={...V,assistantStreamingText:"",assistantTexts:[..._.assistantTexts],call:_.call??null,error:null,isConnected:_.status==="active",partial:_.partial,reconnect:V.reconnect.status==="reconnecting"?{...V.reconnect,lastResumedAt:Date.now(),nextAttemptAt:void 0,status:"resumed"}:V.reconnect,scenarioId:_.scenarioId??V.scenarioId,sessionId:_.sessionId,sessionMetadata:_.sessionMetadata??V.sessionMetadata,status:_.status,turns:[..._.turns]};break;case"session":V={...V,error:null,paused:_.paused??!1,pauseExpiresAt:_.pauseExpiresAt,scenarioId:_.scenarioId??V.scenarioId,isConnected:_.status==="active",sessionId:_.sessionId,sessionMetadata:_.sessionMetadata??V.sessionMetadata,status:_.status};break;case"turn":A="",V={...V,partial:"",turns:[...V.turns,_.turn]};break}g()},getServerSnapshot:()=>V,getSnapshot:()=>V,subscribe:(_)=>{return C.add(_),()=>{C.delete(_)}}}};var t=(V,A={})=>{let C=a(V,A),g=p(),H=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,_=new Set,D=!1,X=(W)=>Promise.resolve().then(()=>{if(D)return;if(!W?.sessionId&&!W?.scenarioId)return;C.start(W),H?.start()}),R=()=>{_.forEach((W)=>W())},O=()=>{if(!A.reconnectReportPath||typeof fetch>"u")return;let W=g.getSnapshot(),U=JSON.stringify({at:Date.now(),reconnect:W.reconnect,scenarioId:W.scenarioId,sessionId:C.getSessionId(),turnIds:W.turns.map((T)=>T.id)});fetch(A.reconnectReportPath,{body:U,headers:{"Content-Type":"application/json"},keepalive:!0,method:"POST"}).catch(()=>{})},L=C.subscribe((W)=>{let U=i(W);if(U){if(g.dispatch(U),W.type==="connection")O();R()}});return{start:X,get assistantAudio(){return g.getSnapshot().assistantAudio},get assistantTexts(){return g.getSnapshot().assistantTexts},get assistantStreamingText(){return g.getSnapshot().assistantStreamingText},get call(){return g.getSnapshot().call},callControl(W){return C.callControl(W)},close(W){D=!0,L(),H?.close(),C.close(W),g.dispatch({type:"disconnected"}),R()},disconnect(){D=!0,L(),H?.close(),C.disconnect(),g.dispatch({type:"disconnected"}),R()},endTurn(){C.endTurn()},get error(){return g.getSnapshot().error},getServerSnapshot(){return g.getServerSnapshot()},getSnapshot(){return g.getSnapshot()},get isConnected(){return g.getSnapshot().isConnected},get partial(){return g.getSnapshot().partial},get paused(){return g.getSnapshot().paused},get pauseExpiresAt(){return g.getSnapshot().pauseExpiresAt},get reconnect(){return g.getSnapshot().reconnect},get scenarioId(){return g.getSnapshot().scenarioId},sendAudio(W){C.sendAudio(W)},get sessionId(){return C.getSessionId()},get sessionMetadata(){return g.getSnapshot().sessionMetadata},simulateDisconnect(){C.simulateDisconnect()},get status(){return g.getSnapshot().status},subscribe(W){return _.add(W),()=>{_.delete(W)}},get turns(){return g.getSnapshot().turns}}};var e=(V)=>{if(!V||V.enabled===!1)return;return{enabled:!0,maxGain:V.maxGain??3,noiseGateAttenuation:V.noiseGateAttenuation??0.15,noiseGateThreshold:V.noiseGateThreshold??0.006,targetLevel:V.targetLevel??0.08}};var s0={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}},a0={"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 V0=(V)=>{let A=V?.profile??"fast",C=V?.qualityProfile??"general",g=s0[A],H=a0[C],_=V?.silenceMs??H.silenceMs??g.silenceMs;return{profile:A,qualityProfile:C,minSilenceMs:Math.min(_,V?.minSilenceMs??H.minSilenceMs??g.minSilenceMs),silenceMs:_,speechThreshold:V?.speechThreshold??H.speechThreshold??g.speechThreshold,transcriptStabilityMs:V?.transcriptStabilityMs??H.transcriptStabilityMs??g.transcriptStabilityMs}};var p0={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"}}},A0=(V="default")=>{let A=p0[V];return{audioConditioning:e(A.audioConditioning),capture:{channelCount:A.capture?.channelCount??1,sampleRateHz:A.capture?.sampleRateHz??16000},connection:{...A.connection},name:V,sttLifecycle:A.sttLifecycle??"continuous",turnDetection:V0(A.turnDetection)}};var t0=(V)=>({assistantAudio:[...V.assistantAudio],assistantStreamingText:V.assistantStreamingText,assistantTexts:[...V.assistantTexts],call:V.call,error:V.error,isConnected:V.isConnected,isRecording:!1,paused:V.paused,pauseExpiresAt:V.pauseExpiresAt,partial:V.partial,reconnect:V.reconnect,recordingError:null,sessionId:V.sessionId,sessionMetadata:V.sessionMetadata,scenarioId:V.scenarioId,status:V.status,turns:[...V.turns]}),g0=(V,A={})=>{let C=A0(A.preset),g=t(V,{...C.connection,...A.connection}),H=null,_=0,D=!1,X=null,R=t0(g),O=new Set,L=()=>{for(let G of O)G()},W=()=>{if(R={...R,assistantAudio:[...g.assistantAudio],assistantStreamingText:g.assistantStreamingText,assistantTexts:[...g.assistantTexts],call:g.call,error:g.error,isConnected:g.isConnected,paused:g.paused,pauseExpiresAt:g.pauseExpiresAt,partial:g.partial,reconnect:g.reconnect,sessionId:g.sessionId,sessionMetadata:g.sessionMetadata,scenarioId:g.scenarioId,status:g.status,turns:[...g.turns]},A.autoStopOnComplete!==!1&&R.status==="completed"&&R.isRecording)H?.stop(),H=null,R={...R,isRecording:!1};L()},U=g.subscribe(W);W();let T=()=>{if(H)return H;return H=v({channelCount:A.capture?.channelCount??C.capture.channelCount,onLevel:A.capture?.onLevel,onAudio:(G)=>{if(A.capture?.onAudio){A.capture.onAudio(G,g.sendAudio);return}g.sendAudio(G)},sampleRateHz:A.capture?.sampleRateHz??C.capture.sampleRateHz,...A.capture?.stream?{stream:A.capture.stream}:{}}),H},w=()=>{_+=1,H?.stop(),H=null,R={...R,isRecording:!1},L()},Z=async()=>{if(D)throw Error("Voice controller is closed.");if(R.isRecording)return;if(X)return X;let G=++_,K=T(),$=(async()=>{try{if(R={...R,recordingError:null},L(),await K.start(),D||G!==_||H!==K){K.stop();return}R={...R,isRecording:!0},L()}catch(J){if(K.stop(),G!==_||H!==K)throw J;throw H=null,R={...R,isRecording:!1,recordingError:J instanceof Error?J.message:String(J)},L(),J}})().finally(()=>{if(X===$)X=null});return X=$,X};return{close:(G)=>{D=!0,U(),w(),g.close(G)},disconnect:()=>{D=!0,U(),w(),g.disconnect()},startRecording:Z,stopRecording:w,get assistantAudio(){return R.assistantAudio},get assistantTexts(){return R.assistantTexts},get assistantStreamingText(){return R.assistantStreamingText},bindHTMX(G){return d(g,G)},get call(){return R.call},callControl:(G)=>g.callControl(G),endTurn:()=>g.endTurn(),get error(){return R.error},getServerSnapshot:()=>R,getSnapshot:()=>R,get isConnected(){return R.isConnected},get isRecording(){return R.isRecording},get partial(){return R.partial},get paused(){return R.paused},get pauseExpiresAt(){return R.pauseExpiresAt},get reconnect(){return R.reconnect},get recordingError(){return R.recordingError},get scenarioId(){return R.scenarioId},sendAudio:(G)=>g.sendAudio(G),get sessionId(){return R.sessionId},get sessionMetadata(){return R.sessionMetadata},simulateDisconnect:()=>g.simulateDisconnect(),get status(){return R.status},subscribe:(G)=>{return O.add(G),()=>{O.delete(G)}},toggleRecording:async()=>{if(R.isRecording){w();return}await Z()},get turns(){return R.turns}}};var z=(V)=>String(V).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;");var C0=(V)=>{if(!V.isConnected)return"idle";if(V.isPlaying)return"speaking";if(V.isRecording&&V.hasActivePartial)return"listening";if(V.isRecording)return"listening";if(V.lastTranscriptAt&&!V.lastAssistantAt)return"thinking";if(V.lastTranscriptAt&&V.lastAssistantAt&&V.lastTranscriptAt>V.lastAssistantAt)return"thinking";return"idle"};var e0={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},VV={callEnded:"Call ended",connecting:"Connecting…",endCall:"End call",idle:"Idle",listening:"Listening",mute:"Mute",speaking:"Speaking",startCall:"Start call",thinking:"Thinking",unmute:"Unmute"},AV=(V,A)=>{switch(V){case"listening":return A.listening;case"speaking":return A.speaking;case"thinking":return A.thinking;case"idle":return A.idle}},_0=(V)=>{let A={...e0,...V.theme},C={...VV,...V.labels},g=V.state.assistantAudio.at(-1)?.receivedAt,H=V.state.turns.at(-1)?.committedAt,_=C0({hasActivePartial:V.state.partial.length>0,isConnected:V.state.isConnected,isPlaying:!1,isRecording:V.state.isRecording,lastAssistantAt:g,lastTranscriptAt:H}),D=!V.state.isConnected&&V.state.status!=="idle"&&!V.state.error,X=V.state.error?"Error":D?C.connecting:V.state.status==="completed"?C.callEnded:AV(_,C);return{agentState:_,classes:{container:`absolute-voice-widget absolute-voice-widget--${_}`,dot:`absolute-voice-widget__dot${V.state.error?" absolute-voice-widget__dot--error":""}`},controls:{canEnd:V.state.isConnected,canMute:V.state.isRecording,canStart:!V.state.isRecording&&V.state.status!=="completed"},errorMessage:V.state.error??void 0,labels:C,partial:V.state.partial||void 0,statusLabel:X,theme:A,title:V.title??"Voice"}},gV=(V)=>typeof V==="number"?`${V}px`:V,T0=(V)=>{let A=V.theme,C=`background:${A.background};border-radius:${gV(A.radius)};color:${A.foreground};font-family:${A.fontFamily};min-width:240px;padding:20px 22px;`,g=`background:${V.errorMessage?A.errorAccent:V.agentState==="idle"?"rgba(148,163,184,0.6)":A.accent};border-radius:50%;height:10px;width:10px;`,H=[];if(V.controls.canStart)H.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;">${z(V.labels.startCall)}</button>`);if(V.controls.canMute)H.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;">${z(V.labels.mute)}</button>`);if(V.controls.canEnd)H.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;">${z(V.labels.endCall)}</button>`);return`<div role="region" aria-live="polite" data-agent-state="${V.agentState}" class="${z(V.classes.container)}" style="${C}">
2
2
  <div style="align-items:center;display:flex;gap:10px;margin-bottom:12px;">
3
- <span aria-hidden="true" class="${z(V.classes.dot)}" style="${A}"></span>
3
+ <span aria-hidden="true" class="${z(V.classes.dot)}" style="${g}"></span>
4
4
  <strong style="font-size:15px;">${z(V.title)}</strong>
5
5
  <span style="font-size:13px;margin-left:auto;opacity:0.7;">${z(V.statusLabel)}</span>
6
6
  </div>
7
7
  ${V.partial?`<p style="font-size:13px;margin:8px 0 12px;opacity:0.85;word-break:break-word;">“${z(V.partial)}”</p>`:""}
8
- <div style="display:flex;gap:10px;">${R.join("")}</div>
9
- ${V.errorMessage?`<p style="color:${g.errorAccent};font-size:12px;margin-top:12px;">${z(V.errorMessage)}</p>`:""}
10
- </div>`};var CV=(V)=>{if(typeof V!=="string")return V;let g=document.querySelector(V);if(!g)throw Error(`AbsoluteVoice.mount: no element matches "${V}"`);return g},$0=(V,g={})=>{let C=CV(V),A=A0(g.path??"/voice",g.controllerOptions),R=null,_=null,D=()=>{let H=_0({...g.labels!==void 0?{labels:g.labels}:{},state:{assistantAudio:A.assistantAudio,error:A.error,isConnected:A.isConnected,isRecording:A.isRecording,partial:A.partial,status:A.status,turns:A.turns},...g.theme!==void 0?{theme:g.theme}:{},...g.title!==void 0?{title:g.title}:{}});C.innerHTML=T0(H);for(let O of C.querySelectorAll("button[data-action]")){let{action:L}=O.dataset;O.addEventListener("click",()=>{if(L==="start")A.startRecording();else if(L==="mute")A.stopRecording();else if(L==="end")A.close()})}if(A.error&&A.error!==R)R=A.error,g.onError?.(A.error);if(A.status!==_)_=A.status,g.onStatusChange?.(A.status)},X=A.subscribe(D);if(D(),g.autoStart)A.startRecording();return{controller:A,async end(){await A.close()},mute(){A.stopRecording()},async start(){await A.startRecording()},unmount(){X(),A.close(),C.innerHTML=""}}},R0="0.0.22-beta.516",H0={mount:$0,version:R0};if(typeof globalThis<"u")globalThis.AbsoluteVoice=H0;var TV=H0;})();
8
+ <div style="display:flex;gap:10px;">${H.join("")}</div>
9
+ ${V.errorMessage?`<p style="color:${A.errorAccent};font-size:12px;margin-top:12px;">${z(V.errorMessage)}</p>`:""}
10
+ </div>`};var CV=(V)=>{if(typeof V!=="string")return V;let A=document.querySelector(V);if(!A)throw Error(`AbsoluteVoice.mount: no element matches "${V}"`);return A},$0=(V,A={})=>{let C=CV(V),g=g0(A.path??"/voice",A.controllerOptions),H=null,_=null,D=()=>{let R=_0({...A.labels!==void 0?{labels:A.labels}:{},state:{assistantAudio:g.assistantAudio,error:g.error,isConnected:g.isConnected,isRecording:g.isRecording,partial:g.partial,status:g.status,turns:g.turns},...A.theme!==void 0?{theme:A.theme}:{},...A.title!==void 0?{title:A.title}:{}});C.innerHTML=T0(R);for(let O of C.querySelectorAll("button[data-action]")){let{action:L}=O.dataset;O.addEventListener("click",()=>{if(L==="start")g.startRecording();else if(L==="mute")g.stopRecording();else if(L==="end")g.close()})}if(g.error&&g.error!==H)H=g.error,A.onError?.(g.error);if(g.status!==_)_=g.status,A.onStatusChange?.(g.status)},X=g.subscribe(D);if(D(),A.autoStart)g.startRecording();return{controller:g,async end(){await g.close()},mute(){g.stopRecording()},async start(){await g.startRecording()},unmount(){X(),g.close(),C.innerHTML=""}}},R0="0.0.22-beta.516",H0={mount:$0,version:R0};if(typeof globalThis<"u")globalThis.AbsoluteVoice=H0;var TV=H0;})();
@@ -11338,6 +11338,8 @@ var serverMessageToAction = (message) => {
11338
11338
  };
11339
11339
  case "session":
11340
11340
  return {
11341
+ paused: message.paused,
11342
+ pauseExpiresAt: message.pauseExpiresAt,
11341
11343
  sessionId: message.sessionId,
11342
11344
  sessionMetadata: message.sessionMetadata,
11343
11345
  scenarioId: message.scenarioId,
@@ -11928,6 +11930,7 @@ var createInitialState = () => ({
11928
11930
  call: null,
11929
11931
  error: null,
11930
11932
  isConnected: false,
11933
+ paused: false,
11931
11934
  partial: "",
11932
11935
  reconnect: createInitialReconnectState(),
11933
11936
  scenarioId: null,
@@ -12064,6 +12067,8 @@ var createVoiceStreamStore = () => {
12064
12067
  state = {
12065
12068
  ...state,
12066
12069
  error: null,
12070
+ paused: action.paused ?? false,
12071
+ pauseExpiresAt: action.pauseExpiresAt,
12067
12072
  scenarioId: action.scenarioId ?? state.scenarioId,
12068
12073
  isConnected: action.status === "active",
12069
12074
  sessionId: action.sessionId,
@@ -12200,6 +12205,12 @@ var createVoiceStream = (path, options = {}) => {
12200
12205
  get partial() {
12201
12206
  return store.getSnapshot().partial;
12202
12207
  },
12208
+ get paused() {
12209
+ return store.getSnapshot().paused;
12210
+ },
12211
+ get pauseExpiresAt() {
12212
+ return store.getSnapshot().pauseExpiresAt;
12213
+ },
12203
12214
  get reconnect() {
12204
12215
  return store.getSnapshot().reconnect;
12205
12216
  },
@@ -12795,6 +12806,8 @@ var createInitialState2 = (stream) => ({
12795
12806
  error: stream.error,
12796
12807
  isConnected: stream.isConnected,
12797
12808
  isRecording: false,
12809
+ paused: stream.paused,
12810
+ pauseExpiresAt: stream.pauseExpiresAt,
12798
12811
  partial: stream.partial,
12799
12812
  reconnect: stream.reconnect,
12800
12813
  recordingError: null,
@@ -12830,6 +12843,8 @@ var createVoiceController = (path, options = {}) => {
12830
12843
  call: stream.call,
12831
12844
  error: stream.error,
12832
12845
  isConnected: stream.isConnected,
12846
+ paused: stream.paused,
12847
+ pauseExpiresAt: stream.pauseExpiresAt,
12833
12848
  partial: stream.partial,
12834
12849
  reconnect: stream.reconnect,
12835
12850
  sessionId: stream.sessionId,
@@ -12977,6 +12992,12 @@ var createVoiceController = (path, options = {}) => {
12977
12992
  get partial() {
12978
12993
  return state.partial;
12979
12994
  },
12995
+ get paused() {
12996
+ return state.paused;
12997
+ },
12998
+ get pauseExpiresAt() {
12999
+ return state.pauseExpiresAt;
13000
+ },
12980
13001
  get reconnect() {
12981
13002
  return state.reconnect;
12982
13003
  },
@@ -10,6 +10,8 @@ export declare const useVoiceController: <TResult = unknown>(path: string, optio
10
10
  stopRecording: () => void;
11
11
  toggleRecording: () => Promise<void>;
12
12
  call: import("..").VoiceCallLifecycleState | null;
13
+ paused: boolean;
14
+ pauseExpiresAt?: number;
13
15
  sessionMetadata: Record<string, unknown> | null;
14
16
  sessionId: string | null;
15
17
  scenarioId: string | null;
@@ -6,6 +6,8 @@ export declare const useVoiceStream: <TResult = unknown>(path: string, options?:
6
6
  sendAudio: (audio: Uint8Array | ArrayBuffer) => void;
7
7
  simulateDisconnect: () => void;
8
8
  call: import("..").VoiceCallLifecycleState | null;
9
+ paused: boolean;
10
+ pauseExpiresAt?: number;
9
11
  sessionMetadata: Record<string, unknown> | null;
10
12
  sessionId: string | null;
11
13
  scenarioId: string | null;
@@ -707,6 +707,8 @@ var serverMessageToAction = (message) => {
707
707
  };
708
708
  case "session":
709
709
  return {
710
+ paused: message.paused,
711
+ pauseExpiresAt: message.pauseExpiresAt,
710
712
  sessionId: message.sessionId,
711
713
  sessionMetadata: message.sessionMetadata,
712
714
  scenarioId: message.scenarioId,
@@ -1297,6 +1299,7 @@ var createInitialState = () => ({
1297
1299
  call: null,
1298
1300
  error: null,
1299
1301
  isConnected: false,
1302
+ paused: false,
1300
1303
  partial: "",
1301
1304
  reconnect: createInitialReconnectState(),
1302
1305
  scenarioId: null,
@@ -1433,6 +1436,8 @@ var createVoiceStreamStore = () => {
1433
1436
  state = {
1434
1437
  ...state,
1435
1438
  error: null,
1439
+ paused: action.paused ?? false,
1440
+ pauseExpiresAt: action.pauseExpiresAt,
1436
1441
  scenarioId: action.scenarioId ?? state.scenarioId,
1437
1442
  isConnected: action.status === "active",
1438
1443
  sessionId: action.sessionId,
@@ -1569,6 +1574,12 @@ var createVoiceStream = (path, options = {}) => {
1569
1574
  get partial() {
1570
1575
  return store.getSnapshot().partial;
1571
1576
  },
1577
+ get paused() {
1578
+ return store.getSnapshot().paused;
1579
+ },
1580
+ get pauseExpiresAt() {
1581
+ return store.getSnapshot().pauseExpiresAt;
1582
+ },
1572
1583
  get reconnect() {
1573
1584
  return store.getSnapshot().reconnect;
1574
1585
  },
@@ -1932,6 +1943,8 @@ var createInitialState2 = (stream) => ({
1932
1943
  error: stream.error,
1933
1944
  isConnected: stream.isConnected,
1934
1945
  isRecording: false,
1946
+ paused: stream.paused,
1947
+ pauseExpiresAt: stream.pauseExpiresAt,
1935
1948
  partial: stream.partial,
1936
1949
  reconnect: stream.reconnect,
1937
1950
  recordingError: null,
@@ -1967,6 +1980,8 @@ var createVoiceController = (path, options = {}) => {
1967
1980
  call: stream.call,
1968
1981
  error: stream.error,
1969
1982
  isConnected: stream.isConnected,
1983
+ paused: stream.paused,
1984
+ pauseExpiresAt: stream.pauseExpiresAt,
1970
1985
  partial: stream.partial,
1971
1986
  reconnect: stream.reconnect,
1972
1987
  sessionId: stream.sessionId,
@@ -2114,6 +2129,12 @@ var createVoiceController = (path, options = {}) => {
2114
2129
  get partial() {
2115
2130
  return state.partial;
2116
2131
  },
2132
+ get paused() {
2133
+ return state.paused;
2134
+ },
2135
+ get pauseExpiresAt() {
2136
+ return state.pauseExpiresAt;
2137
+ },
2117
2138
  get reconnect() {
2118
2139
  return state.reconnect;
2119
2140
  },
@@ -2928,6 +2928,8 @@ var serverMessageToAction = (message) => {
2928
2928
  };
2929
2929
  case "session":
2930
2930
  return {
2931
+ paused: message.paused,
2932
+ pauseExpiresAt: message.pauseExpiresAt,
2931
2933
  sessionId: message.sessionId,
2932
2934
  sessionMetadata: message.sessionMetadata,
2933
2935
  scenarioId: message.scenarioId,
@@ -3518,6 +3520,7 @@ var createInitialState2 = () => ({
3518
3520
  call: null,
3519
3521
  error: null,
3520
3522
  isConnected: false,
3523
+ paused: false,
3521
3524
  partial: "",
3522
3525
  reconnect: createInitialReconnectState(),
3523
3526
  scenarioId: null,
@@ -3654,6 +3657,8 @@ var createVoiceStreamStore = () => {
3654
3657
  state = {
3655
3658
  ...state,
3656
3659
  error: null,
3660
+ paused: action.paused ?? false,
3661
+ pauseExpiresAt: action.pauseExpiresAt,
3657
3662
  scenarioId: action.scenarioId ?? state.scenarioId,
3658
3663
  isConnected: action.status === "active",
3659
3664
  sessionId: action.sessionId,
@@ -3790,6 +3795,12 @@ var createVoiceStream = (path, options = {}) => {
3790
3795
  get partial() {
3791
3796
  return store.getSnapshot().partial;
3792
3797
  },
3798
+ get paused() {
3799
+ return store.getSnapshot().paused;
3800
+ },
3801
+ get pauseExpiresAt() {
3802
+ return store.getSnapshot().pauseExpiresAt;
3803
+ },
3793
3804
  get reconnect() {
3794
3805
  return store.getSnapshot().reconnect;
3795
3806
  },
@@ -4153,6 +4164,8 @@ var createInitialState3 = (stream) => ({
4153
4164
  error: stream.error,
4154
4165
  isConnected: stream.isConnected,
4155
4166
  isRecording: false,
4167
+ paused: stream.paused,
4168
+ pauseExpiresAt: stream.pauseExpiresAt,
4156
4169
  partial: stream.partial,
4157
4170
  reconnect: stream.reconnect,
4158
4171
  recordingError: null,
@@ -4188,6 +4201,8 @@ var createVoiceController = (path, options = {}) => {
4188
4201
  call: stream.call,
4189
4202
  error: stream.error,
4190
4203
  isConnected: stream.isConnected,
4204
+ paused: stream.paused,
4205
+ pauseExpiresAt: stream.pauseExpiresAt,
4191
4206
  partial: stream.partial,
4192
4207
  reconnect: stream.reconnect,
4193
4208
  sessionId: stream.sessionId,
@@ -4335,6 +4350,12 @@ var createVoiceController = (path, options = {}) => {
4335
4350
  get partial() {
4336
4351
  return state.partial;
4337
4352
  },
4353
+ get paused() {
4354
+ return state.paused;
4355
+ },
4356
+ get pauseExpiresAt() {
4357
+ return state.pauseExpiresAt;
4358
+ },
4338
4359
  get reconnect() {
4339
4360
  return state.reconnect;
4340
4361
  },
package/dist/vue/index.js CHANGED
@@ -10734,6 +10734,8 @@ var serverMessageToAction = (message) => {
10734
10734
  };
10735
10735
  case "session":
10736
10736
  return {
10737
+ paused: message.paused,
10738
+ pauseExpiresAt: message.pauseExpiresAt,
10737
10739
  sessionId: message.sessionId,
10738
10740
  sessionMetadata: message.sessionMetadata,
10739
10741
  scenarioId: message.scenarioId,
@@ -11324,6 +11326,7 @@ var createInitialState = () => ({
11324
11326
  call: null,
11325
11327
  error: null,
11326
11328
  isConnected: false,
11329
+ paused: false,
11327
11330
  partial: "",
11328
11331
  reconnect: createInitialReconnectState(),
11329
11332
  scenarioId: null,
@@ -11460,6 +11463,8 @@ var createVoiceStreamStore = () => {
11460
11463
  state = {
11461
11464
  ...state,
11462
11465
  error: null,
11466
+ paused: action.paused ?? false,
11467
+ pauseExpiresAt: action.pauseExpiresAt,
11463
11468
  scenarioId: action.scenarioId ?? state.scenarioId,
11464
11469
  isConnected: action.status === "active",
11465
11470
  sessionId: action.sessionId,
@@ -11596,6 +11601,12 @@ var createVoiceStream = (path, options = {}) => {
11596
11601
  get partial() {
11597
11602
  return store.getSnapshot().partial;
11598
11603
  },
11604
+ get paused() {
11605
+ return store.getSnapshot().paused;
11606
+ },
11607
+ get pauseExpiresAt() {
11608
+ return store.getSnapshot().pauseExpiresAt;
11609
+ },
11599
11610
  get reconnect() {
11600
11611
  return store.getSnapshot().reconnect;
11601
11612
  },
@@ -12212,6 +12223,8 @@ var createInitialState2 = (stream) => ({
12212
12223
  error: stream.error,
12213
12224
  isConnected: stream.isConnected,
12214
12225
  isRecording: false,
12226
+ paused: stream.paused,
12227
+ pauseExpiresAt: stream.pauseExpiresAt,
12215
12228
  partial: stream.partial,
12216
12229
  reconnect: stream.reconnect,
12217
12230
  recordingError: null,
@@ -12247,6 +12260,8 @@ var createVoiceController = (path, options = {}) => {
12247
12260
  call: stream.call,
12248
12261
  error: stream.error,
12249
12262
  isConnected: stream.isConnected,
12263
+ paused: stream.paused,
12264
+ pauseExpiresAt: stream.pauseExpiresAt,
12250
12265
  partial: stream.partial,
12251
12266
  reconnect: stream.reconnect,
12252
12267
  sessionId: stream.sessionId,
@@ -12394,6 +12409,12 @@ var createVoiceController = (path, options = {}) => {
12394
12409
  get partial() {
12395
12410
  return state.partial;
12396
12411
  },
12412
+ get paused() {
12413
+ return state.paused;
12414
+ },
12415
+ get pauseExpiresAt() {
12416
+ return state.pauseExpiresAt;
12417
+ },
12397
12418
  get reconnect() {
12398
12419
  return state.reconnect;
12399
12420
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.661",
3
+ "version": "0.0.22-beta.662",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",