@xmov/avatar 2.4.0 → 2.5.0-alpha.1

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.
Files changed (157) hide show
  1. package/README.md +34 -6
  2. package/package-dist/agent/avatar.cjs +1 -0
  3. package/package-dist/agent/avatar.modern.js +1 -0
  4. package/package-dist/agent/avatar.module.js +1 -0
  5. package/package-dist/agent/avatar.umd.js +1 -0
  6. package/package-dist/agent/index.d.ts +42 -0
  7. package/{dist/agent/types.d.ts → package-dist/agent/public-types.d.ts} +115 -116
  8. package/package-dist/index.cjs +3 -0
  9. package/package-dist/index.d.ts +34 -0
  10. package/package-dist/index.modern.js +1 -0
  11. package/package-dist/index.module.js +1 -0
  12. package/package-dist/index.umd.js +14 -0
  13. package/package-dist/public-types.d.ts +205 -0
  14. package/package.json +41 -33
  15. package/dist/agent/avatar.cjs +0 -1
  16. package/dist/agent/avatar.modern.js +0 -1
  17. package/dist/agent/avatar.module.js +0 -1
  18. package/dist/agent/avatar.umd.js +0 -1
  19. package/dist/agent/index.d.ts +0 -137
  20. package/dist/baseRender/AudioRenderer.d.ts +0 -46
  21. package/dist/baseRender/AudioWorklet.d.ts +0 -78
  22. package/dist/baseRender/AvatarRenderer.d.ts +0 -225
  23. package/dist/baseRender/MSEAudioPlayer.d.ts +0 -51
  24. package/dist/baseRender/UIRenderer.d.ts +0 -39
  25. package/dist/baseRender/pcm-audio-processor.d.ts +0 -63
  26. package/dist/control/APIForwarder.d.ts +0 -23
  27. package/dist/control/DataCacheQueue.d.ts +0 -69
  28. package/dist/control/EventDispatcher.d.ts +0 -35
  29. package/dist/control/RenderScheduler.d.ts +0 -171
  30. package/dist/control/SaveAndDownload.d.ts +0 -14
  31. package/dist/control/StreamingClient.d.ts +0 -33
  32. package/dist/control/VideoPlayer.d.ts +0 -47
  33. package/dist/control/ttsa.d.ts +0 -125
  34. package/dist/encoding/media-recorder-encoder.d.ts +0 -33
  35. package/dist/encoding/pcm-webm-encoder.d.ts +0 -13
  36. package/dist/encoding/webcodec-opus-encoder.d.ts +0 -41
  37. package/dist/encoding/webm-muxer.d.ts +0 -90
  38. package/dist/index.cjs +0 -2
  39. package/dist/index.cjs.map +0 -1
  40. package/dist/index.d.ts +0 -251
  41. package/dist/index.modern.js +0 -2
  42. package/dist/index.modern.js.map +0 -1
  43. package/dist/index.module.js +0 -2
  44. package/dist/index.module.js.map +0 -1
  45. package/dist/index.umd.js +0 -2
  46. package/dist/index.umd.js.map +0 -1
  47. package/dist/modules/Composition.d.ts +0 -28
  48. package/dist/modules/ResourceManager.d.ts +0 -299
  49. package/dist/modules/TrackRenderer/base-track.d.ts +0 -4
  50. package/dist/modules/TrackRenderer/index.d.ts +0 -12
  51. package/dist/modules/TrackRenderer/render-implements.d.ts +0 -19
  52. package/dist/modules/TrackRenderer/track-pic.d.ts +0 -8
  53. package/dist/modules/TrackRenderer/track-subtitle.d.ts +0 -8
  54. package/dist/modules/cache-manager.d.ts +0 -5
  55. package/dist/modules/decoder.d.ts +0 -84
  56. package/dist/modules/error-handle.d.ts +0 -17
  57. package/dist/modules/network.d.ts +0 -21
  58. package/dist/modules/sentry-reporter.d.ts +0 -58
  59. package/dist/proto/face_data_pb.d.ts +0 -0
  60. package/dist/types/capability.d.ts +0 -15
  61. package/dist/types/error.d.ts +0 -70
  62. package/dist/types/event.d.ts +0 -25
  63. package/dist/types/frame-data.d.ts +0 -107
  64. package/dist/types/index.d.ts +0 -196
  65. package/dist/types/render.d.ts +0 -18
  66. package/dist/utils/DataInterface.d.ts +0 -113
  67. package/dist/utils/GLDevice.d.ts +0 -46
  68. package/dist/utils/GLPipeline.d.ts +0 -84
  69. package/dist/utils/GLPipelineDebugTools.d.ts +0 -5
  70. package/dist/utils/Math.d.ts +0 -21
  71. package/dist/utils/__tests__/capability-checker.test.d.ts +0 -1
  72. package/dist/utils/audio-session.d.ts +0 -11
  73. package/dist/utils/audio.d.ts +0 -1
  74. package/dist/utils/capability-checker.d.ts +0 -28
  75. package/dist/utils/encodeToken.d.ts +0 -14
  76. package/dist/utils/face.d.ts +0 -1
  77. package/dist/utils/float32-decoder.d.ts +0 -26
  78. package/dist/utils/fpsTracker.d.ts +0 -27
  79. package/dist/utils/index.d.ts +0 -22
  80. package/dist/utils/logger.d.ts +0 -9
  81. package/dist/utils/media-recorder-timestamp.d.ts +0 -15
  82. package/dist/utils/pcmAnalyzer.d.ts +0 -40
  83. package/dist/utils/perfermance.d.ts +0 -15
  84. package/dist/utils/request.d.ts +0 -20
  85. package/dist/utils/requestAnimateFrames.d.ts +0 -31
  86. package/dist/utils/time.d.ts +0 -9
  87. package/dist/utils/video-probe-asset.d.ts +0 -28
  88. package/dist/view/DebugOverlay.d.ts +0 -54
  89. package/dist/worker/streaming-video.d.ts +0 -1
  90. package/src/baseRender/AudioRenderer.ts +0 -328
  91. package/src/baseRender/AudioWorklet.ts +0 -776
  92. package/src/baseRender/AvatarRenderer.ts +0 -1550
  93. package/src/baseRender/MSEAudioPlayer.ts +0 -254
  94. package/src/baseRender/UIRenderer.ts +0 -195
  95. package/src/baseRender/pcm-audio-processor.js +0 -267
  96. package/src/control/APIForwarder.ts +0 -67
  97. package/src/control/DataCacheQueue.ts +0 -372
  98. package/src/control/EventDispatcher.ts +0 -106
  99. package/src/control/RenderScheduler.ts +0 -1000
  100. package/src/control/SaveAndDownload.js +0 -77
  101. package/src/control/StreamingClient.ts +0 -138
  102. package/src/control/VideoPlayer.ts +0 -306
  103. package/src/control/ttsa.ts +0 -754
  104. package/src/encoding/media-recorder-encoder.ts +0 -175
  105. package/src/encoding/pcm-webm-encoder.ts +0 -72
  106. package/src/encoding/webcodec-opus-encoder.ts +0 -258
  107. package/src/encoding/webm-muxer.ts +0 -337
  108. package/src/global.d.ts +0 -112
  109. package/src/index.ts +0 -2053
  110. package/src/modules/Composition.ts +0 -79
  111. package/src/modules/ResourceManager.ts +0 -926
  112. package/src/modules/TrackRenderer/base-track.ts +0 -7
  113. package/src/modules/TrackRenderer/index.ts +0 -40
  114. package/src/modules/TrackRenderer/render-implements.ts +0 -269
  115. package/src/modules/TrackRenderer/track-pic.ts +0 -19
  116. package/src/modules/TrackRenderer/track-subtitle.ts +0 -16
  117. package/src/modules/cache-manager.ts +0 -10
  118. package/src/modules/decoder.ts +0 -548
  119. package/src/modules/error-handle.ts +0 -20
  120. package/src/modules/network.ts +0 -71
  121. package/src/modules/sentry-reporter.ts +0 -171
  122. package/src/proto/face_data.proto +0 -45
  123. package/src/proto/face_data_pb.js +0 -1297
  124. package/src/proto/protobuf.min.js +0 -8
  125. package/src/types/capability.ts +0 -24
  126. package/src/types/error.ts +0 -211
  127. package/src/types/event.ts +0 -38
  128. package/src/types/frame-data.ts +0 -121
  129. package/src/types/index.ts +0 -220
  130. package/src/types/render.ts +0 -18
  131. package/src/utils/DataInterface.ts +0 -746
  132. package/src/utils/GLDevice.ts +0 -286
  133. package/src/utils/GLPipeline.ts +0 -1293
  134. package/src/utils/GLPipelineDebugTools.ts +0 -174
  135. package/src/utils/Math.ts +0 -266
  136. package/src/utils/__tests__/capability-checker.test.ts +0 -159
  137. package/src/utils/audio-session.ts +0 -144
  138. package/src/utils/audio.ts +0 -44
  139. package/src/utils/blueimp-md5.d.ts +0 -3
  140. package/src/utils/capability-checker.ts +0 -762
  141. package/src/utils/encodeToken.ts +0 -115
  142. package/src/utils/face.ts +0 -29
  143. package/src/utils/float32-decoder.js +0 -130
  144. package/src/utils/fpsTracker.ts +0 -100
  145. package/src/utils/index.ts +0 -182
  146. package/src/utils/logger.js +0 -36
  147. package/src/utils/media-recorder-timestamp.ts +0 -79
  148. package/src/utils/pcmAnalyzer.ts +0 -154
  149. package/src/utils/perfermance.ts +0 -141
  150. package/src/utils/request.ts +0 -107
  151. package/src/utils/requestAnimateFrames.ts +0 -195
  152. package/src/utils/time.ts +0 -32
  153. package/src/utils/video-probe-asset.ts +0 -99
  154. package/src/view/DebugOverlay.ts +0 -409
  155. package/src/worker/streaming-video.ts +0 -4647
  156. /package/{dist → package-dist}/agent/index.cjs +0 -0
  157. /package/{dist → package-dist}/agent/index.umd.js +0 -0
@@ -1 +0,0 @@
1
- import e from"@xmov/avatar";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)({}).hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e},t.apply(null,arguments)}var n,i,s,r;!function(e){e[e.CONTAINER_NOT_FOUND=10001]="CONTAINER_NOT_FOUND",e[e.CONNECT_SOCKET_ERROR=10002]="CONNECT_SOCKET_ERROR",e[e.START_SESSION_ERROR=10003]="START_SESSION_ERROR",e[e.STOP_SESSION_ERROR=10004]="STOP_SESSION_ERROR",e[e.INIT_ERROR=10005]="INIT_ERROR",e[e.SOCKET_QUIT=10006]="SOCKET_QUIT",e[e.SOCKET_DISCONNECT=10007]="SOCKET_DISCONNECT",e[e.VIDEO_FRAME_EXTRACT_ERROR=20001]="VIDEO_FRAME_EXTRACT_ERROR",e[e.INIT_WORKER_ERROR=20002]="INIT_WORKER_ERROR",e[e.PROCESS_VIDEO_STREAM_ERROR=20003]="PROCESS_VIDEO_STREAM_ERROR",e[e.FACE_PROCESSING_ERROR=20004]="FACE_PROCESSING_ERROR",e[e.RENDER_BODY_ERROR=20005]="RENDER_BODY_ERROR",e[e.RENDER_FACE_ERROR=20006]="RENDER_FACE_ERROR",e[e.WebGL_RENDER_ERROR=20007]="WebGL_RENDER_ERROR",e[e.RENDER_DATA_MISSING=20008]="RENDER_DATA_MISSING",e[e.RENDER_FACE_DATA_MISSING=20009]="RENDER_FACE_DATA_MISSING",e[e.EVENT_WITHOUT_SPEECH_ID=20010]="EVENT_WITHOUT_SPEECH_ID",e[e.EVENT_TRIGGERED=20011]="EVENT_TRIGGERED",e[e.BACKGROUND_IMAGE_LOAD_ERROR=30001]="BACKGROUND_IMAGE_LOAD_ERROR",e[e.FACE_BIN_LOAD_ERROR=30002]="FACE_BIN_LOAD_ERROR",e[e.INVALID_BODY_NAME=30003]="INVALID_BODY_NAME",e[e.VIDEO_DOWNLOAD_ERROR=30004]="VIDEO_DOWNLOAD_ERROR",e[e.BODY_DATA_EXPIRED=30005]="BODY_DATA_EXPIRED",e[e.EVENT_SPEAK_START_EXPIRED=30006]="EVENT_SPEAK_START_EXPIRED",e[e.EVENT_VOICE_START_EXPIRED=30007]="EVENT_VOICE_START_EXPIRED",e[e.AUDIO_DECODE_ERROR=40001]="AUDIO_DECODE_ERROR",e[e.FACE_DECODE_ERROR=40002]="FACE_DECODE_ERROR",e[e.VIDEO_DECODE_ERROR=40003]="VIDEO_DECODE_ERROR",e[e.EVENT_DECODE_ERROR=40004]="EVENT_DECODE_ERROR",e[e.INVALID_DATA_STRUCTURE=40005]="INVALID_DATA_STRUCTURE",e[e.TTSA_ERROR=40006]="TTSA_ERROR",e[e.AUDIO_DATA_EXPIRED=40007]="AUDIO_DATA_EXPIRED",e[e.NETWORK_DOWN=50001]="NETWORK_DOWN",e[e.NETWORK_UP=50002]="NETWORK_UP",e[e.NETWORK_RETRY=50003]="NETWORK_RETRY",e[e.NETWORK_BREAK=50004]="NETWORK_BREAK",e[e.WEBGL_CONTEXT_LOST=60001]="WEBGL_CONTEXT_LOST",e[e.WEBGL_CONTEXT_RESTORED=60002]="WEBGL_CONTEXT_RESTORED",e[e.WEBGL_CONTEXT_RESTORE_TIMEOUT=60003]="WEBGL_CONTEXT_RESTORE_TIMEOUT",e[e.WEBGL_CONTEXT_RECOVERED=60004]="WEBGL_CONTEXT_RECOVERED",e[e.WEBGL_CONTEXT_RECOVERY_FAILED=60005]="WEBGL_CONTEXT_RECOVERY_FAILED",e[e.WEBGL_CONTEXT_RECOVERY_MAX_ATTEMPTS=60006]="WEBGL_CONTEXT_RECOVERY_MAX_ATTEMPTS",e[e.WEBGL_RESOLUTION_RESTORED=60007]="WEBGL_RESOLUTION_RESTORED",e[e.WEBGL_CONTEXT_MANUAL_RESTARTED=60008]="WEBGL_CONTEXT_MANUAL_RESTARTED"}(n||(n={})),function(e){e[e.online=0]="online",e[e.offline=1]="offline",e[e.network_on=2]="network_on",e[e.network_off=3]="network_off",e[e.close=4]="close",e[e.visible=5]="visible",e[e.invisible=6]="invisible",e[e.stopped=7]="stopped"}(i||(i={})),function(e){e.init="init",e.rendering="rendering",e.pausing="pausing",e.paused="paused",e.resumed="resumed",e.stopped="stopped"}(s||(s={})),function(e){e.normal="normal",e.invisible="invisible"}(r||(r={}));const a=2097152;class o{constructor(e){var t;this.ws=null,this.connectPromise=null,this.rejectConnect=null,this.options=e,this.audioInputEnabled=null==(t=e.audioInputEnabled)||t;const n=e.WebSocketCtor||globalThis.WebSocket;if(!n)throw new Error("当前环境不支持 WebSocket");this.WebSocketCtor=n}get isOpen(){var e;return(null==(e=this.ws)?void 0:e.readyState)===this.WebSocketCtor.OPEN}connect(){var e,t;if(this.isOpen)return Promise.resolve();if(this.connectPromise)return this.connectPromise;let n;return null==(e=(t=this.options).onStateChange)||e.call(t,"connecting"),n=new Promise((e,t)=>{this.rejectConnect=t;let i=!1;const s=new this.WebSocketCtor(this.buildWsUrl(this.options.wsUrl,this.options.token));this.ws=s,s.onopen=()=>{var t,r;this.ws===s&&(i=!0,this.connectPromise===n&&(this.connectPromise=null),this.rejectConnect=null,null==(t=(r=this.options).onStateChange)||t.call(r,"open"),e())},s.onmessage=e=>{if(this.ws!==s)return;const t=this.parseMessage(e.data);var n,i;t&&(null==(n=(i=this.options).onEvent)||n.call(i,t))},s.onerror=()=>{var e,r,a,o;if(this.ws!==s)return;const l=new Error("E2E WebSocket 连接异常");i||(i=!0,this.connectPromise===n&&(this.connectPromise=null),this.rejectConnect=null,t(l)),null==(e=(r=this.options).onStateChange)||e.call(r,"error"),null==(a=(o=this.options).onError)||a.call(o,l)},s.onclose=e=>{var r,a,o,l;this.ws===s&&(this.ws=null,i||(i=!0,this.connectPromise===n&&(this.connectPromise=null),this.rejectConnect=null,t(new Error(`E2E WebSocket 已关闭: ${e.code} ${e.reason||""}`.trim()))),null==(r=(a=this.options).onStateChange)||r.call(a,"closed"),null==(o=(l=this.options).onClose)||o.call(l,e))}}),this.connectPromise=n,this.connectPromise}disconnect(e=1e3,t="client_close"){const n=this.detachSocket();n&&this.closeSocket(n,e,t)}disconnectAndWait(e=1e3,t="client_close",n=3e3){const i=this.ws;return i?(this.cancelPendingConnection(),new Promise(s=>{const r=i.onclose;let a,o=!1;const l=e=>{o||(o=!0,void 0!==a&&globalThis.clearTimeout(a),this.ws===i&&(this.ws=null),i.onclose=r,s(e))};i.onclose=e=>{try{null==r||r.call(i,e)}finally{l(!0)}},a=globalThis.setTimeout(()=>l(!1),Math.max(0,n));try{this.closeSocket(i,e,t)}catch(e){l(!1)}})):Promise.resolve(!0)}detachSocket(){if(!this.ws)return null;const e=this.ws;return this.ws=null,this.cancelPendingConnection(),e}cancelPendingConnection(){this.connectPromise=null;const e=this.rejectConnect;this.rejectConnect=null,null==e||e(new Error("E2E WebSocket 连接已取消"))}closeSocket(e,t,n){e.readyState!==this.WebSocketCtor.OPEN&&e.readyState!==this.WebSocketCtor.CONNECTING||e.close(t,n)}send(e){var t;this.assertOpen(),null==(t=this.ws)||t.send(JSON.stringify(e))}trySend(e){var t;return this.assertOpen(),!(this.ws&&this.ws.bufferedAmount>a||(null==(t=this.ws)||t.send(JSON.stringify(e)),0))}sendBinary(e){var t;if(this.assertOpen(),this.ws&&this.ws.bufferedAmount>a){const e=new Error("E2E WebSocket 发送缓冲区超限");throw e.name="WebSocketBackpressureError",e}null==(t=this.ws)||t.send(e)}ping(){this.send({type:"ping"})}setAudioInputEnabled(e){this.audioInputEnabled=e}assertOpen(){if(!this.isOpen)throw new Error("E2E WebSocket 未连接")}parseMessage(e){if("string"!=typeof e)return null;try{const t=JSON.parse(e);return t&&"string"==typeof t.type?t:null}catch(e){var t,n;return null==(t=(n=this.options).onError)||t.call(n,new Error("E2E WebSocket 消息不是合法 JSON")),null}}buildWsUrl(e,t){try{const n=new URL(e);return!t||n.searchParams.has("token")||n.searchParams.has("e2e_token")||n.searchParams.set("token",t),this.updateAudioInputQuery(n.searchParams),n.toString()}catch(n){const[i,s=""]=e.split("?",2),r=new URLSearchParams(s);!t||r.has("token")||r.has("e2e_token")||r.set("token",t),this.updateAudioInputQuery(r);const a=r.toString();return a?`${i}?${a}`:i}}updateAudioInputQuery(e){this.audioInputEnabled?e.delete("audio_input_off"):e.set("audio_input_off","1")}}const l={format:"webm_opus",mimeType:"audio/webm;codecs=opus",sampleRate:16e3,channels:1,chunkMs:100},h=16e3;class c{constructor(e={}){this.inputTrack=null,this.reader=null,this.writer=null,this.generator=null,this.audioContext=null,this.audioSource=null,this.audioDestination=null,this.pumpPromise=null,this.pumpFinished=!1,this.outputClosed=!1,this.draining=!1,this.inputSampleRate=null,this.resampleBuffer=[],this.resamplePosition=0,this.outputBuffer=[],this.outputTimestamp=null,this.startGeneration=0,this.options=e}async start(e){const t=++this.startGeneration;this.inputTrack=e,this.inputSampleRate=null,this.resampleBuffer=[],this.resamplePosition=0,this.outputBuffer=[],this.outputTimestamp=null,this.pumpFinished=!1,this.outputClosed=!1,this.draining=!1;const n=globalThis,i=n.MediaStreamTrackProcessor,s=n.MediaStreamTrackGenerator,r=n.AudioData;if(!i||!s||!r)return this.startWebAudio(e,n,t);const a=new i({track:e}),o=new s({kind:"audio"}),l=new MediaStream([o]),c=l.getAudioTracks()[0],u=null==c?void 0:c.getSettings();if(void 0!==(null==u?void 0:u.sampleRate)&&u.sampleRate!==h||void 0!==(null==u?void 0:u.channelCount)&&1!==u.channelCount)throw o.stop(),this.unsupported(`浏览器音频输出格式不符合要求: ${(null==u?void 0:u.sampleRate)||"unknown"} Hz / ${(null==u?void 0:u.channelCount)||"unknown"} channel`);try{this.reader=a.readable.getReader(),this.writer=o.writable.getWriter()}catch(t){throw o.stop(),"ended"!==e.readyState&&e.stop(),this.inputTrack=null,t}return this.generator=o,this.pumpPromise=this.pump(r),l}async startWebAudio(e,t,n){const i=globalThis.AudioContext||t.webkitAudioContext;if(!i)throw this.unsupported("当前浏览器不支持 16 kHz mono 音频处理");let s=null,r=null,a=null;try{if(s=new i({sampleRate:h}),this.audioContext=s,s.sampleRate!==h)throw this.unsupported(`浏览器无法创建 16 kHz AudioContext: ${s.sampleRate} Hz`);if("suspended"===s.state)try{await s.resume()}catch(e){throw this.contextSuspended(e)}if(this.assertStartActive(n),"running"!==s.state)throw this.contextSuspended();r=s.createMediaStreamSource(new MediaStream([e])),this.audioSource=r,a=s.createMediaStreamDestination(),this.audioDestination=a,a.channelCount=1,a.channelCountMode="explicit",a.channelInterpretation="speakers",r.connect(a);const t=a.stream.getAudioTracks()[0];if(!t)throw new Error("Web Audio 未返回音频输出轨道");return this.validateOutputTrack(t),this.assertStartActive(n),a.stream}catch(t){var o,l;throw null==(o=r)||o.disconnect(),null==(l=a)||l.stream.getTracks().forEach(e=>e.stop()),s&&"closed"!==s.state&&await s.close().catch(()=>{}),"ended"!==e.readyState&&e.stop(),this.inputTrack=null,this.audioContext===s&&(this.audioContext=null,this.audioSource=null,this.audioDestination=null),this.normalizeWebAudioError(t)}}async stop(){await this.drain(),this.audioContext?await this.closeWebAudioOutput():await this.closeOutput()}async drain(){var e;if(this.startGeneration+=1,this.draining=!0,null==(e=this.inputTrack)||e.stop(),this.inputTrack=null,this.audioContext)return;const t=this.pumpPromise;if(t){const e=t.then(()=>!0,()=>!0);var n,i;await Promise.race([e,this.delay(1e3)])||(await Promise.race([null==(n=this.reader)?void 0:n.cancel().catch(()=>{}),this.delay(100)]),await Promise.race([null==(i=this.writer)?void 0:i.abort(new Error("16 kHz mono 音频处理停止超时")).catch(()=>{}),this.delay(100)]),this.stopGenerator())}}async closeOutput(){const e=this.writer;this.outputClosed=!0,e&&this.pumpFinished?await Promise.race([e.close().catch(()=>{}),this.delay(100)]):await Promise.race([null==e?void 0:e.abort(new Error("16 kHz mono 音频处理停止超时")).catch(()=>{}),this.delay(100)]),this.stopGenerator(),e&&this.pumpFinished&&e.releaseLock(),this.reader=null,this.writer=null,this.generator=null,this.pumpPromise=null}async closeWebAudioOutput(){const e=this.audioContext,t=this.audioSource,n=this.audioDestination;this.audioContext=null,this.audioSource=null,this.audioDestination=null,null==t||t.disconnect(),null==n||n.disconnect(),null==n||n.stream.getTracks().forEach(e=>e.stop()),e&&"closed"!==e.state&&await e.close().catch(()=>{})}async pump(e){const t=this.reader,n=this.writer;if(t&&n)try{var i;let a=!1;for(;;){const i=await t.read();if(i.done){a=!0;break}if(!i.value)continue;const s=i.value;try{this.validateAudioData(s);const t=this.toMono(s),i=this.resample(t,s.sampleRate,!1);null===this.outputTimestamp&&(this.outputTimestamp=Number.isFinite(s.timestamp)?s.timestamp:0);for(const t of i)await this.writeChunk(n,e,t)}finally{s.close()}}for(const t of this.resample(new Float32Array,this.inputSampleRate||h,!0))await this.writeChunk(n,e,t);if(a&&!this.draining&&"ended"===(null==(i=this.inputTrack)?void 0:i.readyState)){var s,r;const e=new Error("麦克风音频轨道已结束");e.name="AudioTransformError",null==(s=(r=this.options).onError)||s.call(r,e),this.stopGenerator()}}catch(e){var a,o;const t=e instanceof Error?e:new Error("16 kHz mono 音频处理失败");t.name="AudioTransformError",null==(a=(o=this.options).onError)||a.call(o,t)}finally{t.releaseLock(),this.pumpFinished=!0,this.outputClosed&&n.releaseLock()}}toMono(e){const t=Math.max(1,e.numberOfChannels),n=new Float32Array(e.numberOfFrames);for(let i=0;i<t;i+=1){const s=new Float32Array(e.numberOfFrames);e.copyTo(s,{format:"f32-planar",planeIndex:i});for(let e=0;e<s.length;e+=1)n[e]+=s[e]/t}return n}resample(e,t,n){if(null===this.inputSampleRate)this.inputSampleRate=t;else if(this.inputSampleRate!==t)throw new Error(`输入音频采样率发生变化: ${this.inputSampleRate} -> ${t}`);for(const t of e)this.resampleBuffer.push(t);if(this.resampleBuffer.length>192e3)throw new Error("输入音频重采样缓冲区超限");n&&this.resampleBuffer.length>0&&this.resampleBuffer.push(this.resampleBuffer[this.resampleBuffer.length-1]);const i=t/h,s=[];for(;this.resamplePosition+1<this.resampleBuffer.length;){const e=Math.floor(this.resamplePosition),t=Math.min(e+1,this.resampleBuffer.length-1),n=this.resamplePosition-e;this.outputBuffer.push(this.resampleBuffer[e]*(1-n)+this.resampleBuffer[t]*n),this.resamplePosition+=i;const r=Math.floor(this.resamplePosition);r>0&&(this.resampleBuffer.splice(0,r),this.resamplePosition-=r),this.outputBuffer.length>=320&&s.push(new Float32Array(this.outputBuffer.splice(0,320)))}return n&&this.outputBuffer.length>0&&s.push(new Float32Array(this.outputBuffer.splice(0))),s}async writeChunk(e,t,n){var i;if(!n.length)return;const s=this.outputTimestamp||0,r=new t({format:"f32-planar",sampleRate:h,numberOfFrames:n.length,numberOfChannels:1,timestamp:s,data:n});this.outputTimestamp=s+Math.round(1e6*n.length/h),await e.write(r),r.close();const a=null==(i=this.generator)?void 0:i.getSettings();if(a&&(void 0!==a.sampleRate&&a.sampleRate!==h||void 0!==a.channelCount&&1!==a.channelCount))throw this.unsupported(`浏览器音频输出格式不符合要求: ${a.sampleRate||"unknown"} Hz / ${a.channelCount||"unknown"} channel`)}validateAudioData(e){if(!Number.isFinite(e.sampleRate)||!Number.isInteger(e.sampleRate)||e.sampleRate<8e3||e.sampleRate>192e3)throw new Error(`输入音频采样率无效: ${e.sampleRate}`);if(!Number.isInteger(e.numberOfChannels)||e.numberOfChannels<1||e.numberOfChannels>8)throw new Error(`输入音频声道数无效: ${e.numberOfChannels}`);if(!Number.isInteger(e.numberOfFrames)||e.numberOfFrames<1||e.numberOfFrames>96e3)throw new Error(`输入音频帧数无效: ${e.numberOfFrames}`);if(!Number.isFinite(e.timestamp)||Math.abs(e.timestamp)>1e15)throw new Error(`输入音频时间戳无效: ${e.timestamp}`)}delay(e){return new Promise(t=>{globalThis.setTimeout(()=>t(!1),e)})}stopGenerator(){this.generator&&"ended"!==this.generator.readyState&&this.generator.stop()}unsupported(e,t){const n=new Error(e);return n.name="NotSupportedError",n.agentCode="AUDIO_FIXED_TRACK_UNSUPPORTED",n.retryable=!1,n.cause=t,n}contextSuspended(e){const t=new Error("AudioContext 未运行,请在用户操作后重试");return t.name="NotAllowedError",t.agentCode="AUDIO_CONTEXT_SUSPENDED",t.retryable=!0,t.cause=e,t}assertStartActive(e){if(e!==this.startGeneration){const e=new Error("16 kHz mono 音频处理启动已取消");throw e.name="AbortError",e.agentCode="AUDIO_FIXED_TRACK_CANCELLED",e.retryable=!0,e}}normalizeWebAudioError(e){const t=e instanceof Error?e:new Error(String(e));if(t.agentCode)return t;if("NotSupportedError"===t.name)return this.unsupported(`浏览器无法初始化 16 kHz mono Web Audio: ${t.message}`,t);const n=new Error(`16 kHz mono Web Audio 初始化失败: ${t.message}`);return n.name=t.name,n.agentCode="AUDIO_FIXED_TRACK_FAILED",n.retryable=!0,n.cause=t,n}validateOutputTrack(e){const t=e.getSettings();if(void 0!==t.sampleRate&&t.sampleRate!==h||void 0!==t.channelCount&&1!==t.channelCount)throw this.unsupported(`浏览器音频输出格式不符合要求: ${t.sampleRate||"unknown"} Hz / ${t.channelCount||"unknown"} channel`)}}function u(e){return e.toString(16).padStart(2,"0")}async function d(e,n,i={},s=64){try{const r=n instanceof Blob?await n.arrayBuffer():ArrayBuffer.isView(n)?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):n,a=new Uint8Array(r),o=Array.from(a.slice(0,s)),l=n instanceof Blob?n.type:i.type;console.log(e,t({},i,{size:a.byteLength,type:l,previewLength:o.length,bytes:o,hex:o.map(u).join(" ")}))}catch(t){console.warn(e,"failed to read audio chunk",t)}}const p=new WeakMap,m=new WeakMap;function g(e){return e.audioSession}function E(e,t){try{return e.type=t,e.type===t}catch(e){return!1}}function f(){const e=globalThis.performance;return e&&Number.isFinite(e.timeOrigin)&&"function"==typeof e.now?e.timeOrigin+e.now():Date.now()}class S{constructor(e,t=f){this.timecodeScale=null,this.firstTimecode=null,this.lastTimecode=null,this.lastObservedAt=null,this.lastTimestamp=null,this.chunkMs=e,this.now=t,this.startedAt=t()}resolve(e){const t=this.now(),n=Number.isFinite(e)&&e>=0;if(n&&null===this.firstTimecode&&(this.firstTimecode=e),n&&null===this.timecodeScale&&null!==this.lastTimecode&&e>this.lastTimecode){const n=e-this.lastTimecode,i=null===this.lastObservedAt?0:t-this.lastObservedAt,s=i>=this.chunkMs/4?i:this.chunkMs,r=Math.abs(n-s),a=Math.abs(1e3*n-s);this.timecodeScale=a<r?1e3:1}let i=t-this.chunkMs;const s=n&&null!==this.firstTimecode?e-this.firstTimecode:null;var r;null!==s&&s>=0&&(null!==this.timecodeScale||0===s)&&(i=this.startedAt+s*(null!=(r=this.timecodeScale)?r:1)),null!==this.lastTimestamp&&(i=Math.max(i,this.lastTimestamp+this.chunkMs));const a=Math.max(Math.round(this.startedAt),Math.round(i));return this.lastTimecode=n?e:this.lastTimecode,this.lastObservedAt=t,this.lastTimestamp=a,a}}const R=2e4;function A(e){return{codec:"opus",sampleRate:e.sampleRate,numberOfChannels:e.channels,bitrate:e.bitrate,opus:{format:"opus",frameDuration:R}}}class y{constructor(e={}){this.encoder=null,this.isInitialized=!1,this.pendingEncode=null,this.timestamp=0,this.config=t({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600},e)}static async isSupported(){if("undefined"==typeof AudioEncoder)return!1;try{var e;const t=await AudioEncoder.isConfigSupported(A({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600}));return!0===t.supported&&(null==(e=t.config)||null==(e=e.opus)?void 0:e.frameDuration)===R}catch(e){return!1}}async init(){this.isInitialized||(this.encoder=this.createEncoder(),this.isInitialized=!0)}async encode(e){if(!this.isInitialized||!this.encoder)return Promise.reject(new Error("WebCodecOpusEncoder 未初始化"));if(this.pendingEncode)return Promise.reject(new Error("WebCodecs Opus 编码器仍在处理上一音频块"));const t=new Int16Array(e),n=this.timestamp,i=Math.round(1e6*e.length/this.config.sampleRate),s=n+i,r=i/R;if(!Number.isInteger(r))return Promise.reject(new Error("PCM 音频块无法按 20ms Opus packet 完整分包"));const a=new AudioData({format:"s16",sampleRate:this.config.sampleRate,numberOfFrames:t.length,numberOfChannels:this.config.channels,timestamp:n,data:t}),o=new Promise((e,t)=>{const i=globalThis.setTimeout(()=>{this.failPending(new Error("WebCodecs Opus 编码输出超过 2 秒"))},2e3);this.pendingEncode={startTimestampUs:n,endTimestampUs:s,expectedFrameCount:r,chunks:[],resolve:e,reject:t,timeoutId:i}});try{this.encoder.encode(a),this.timestamp=s}catch(e){this.failPending(e instanceof Error?e:new Error("WebCodecs Opus 编码失败"))}finally{a.close()}return o}reset(){if(this.timestamp=0,this.failPending(new Error("WebCodecs Opus 编码已重置")),this.encoder){try{this.encoder.close()}catch(e){}this.encoder=this.createEncoder()}}async destroy(){const e=this.encoder;if(e){try{await e.flush()}catch(e){}this.failPending(new Error("WebCodecs Opus 编码器已销毁"));try{e.close()}catch(e){}}this.encoder=null,this.isInitialized=!1}createEncoder(){let e;return e=new AudioEncoder({output:t=>{this.encoder===e&&this.handleOutput(t)},error:t=>{if(this.encoder!==e)return;const n=t instanceof Error?t:new Error("WebCodecs Opus 编码失败");(globalThis.avatarSDKLogger||console).error("[WebCodecOpusEncoder] 编码错误:",n),this.failPending(n)}}),e.configure(A(this.config)),e}handleOutput(e){const t=this.pendingEncode;if(!t)return;if(e.timestamp<t.startTimestampUs||e.timestamp>=t.endTimestampUs||null!==e.duration&&e.duration!==R)return void this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频"));if(t.chunks.push(e),t.chunks.length>t.expectedFrameCount)return void this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频"));if(t.chunks.length<t.expectedFrameCount)return;const n=t.chunks.map((e,n)=>{var i,s;const r=new Uint8Array(e.byteLength);e.copyTo(r);const a=null!=(i=null==(s=t.chunks[n+1])?void 0:s.timestamp)?i:t.endTimestampUs;return{data:r,durationMs:(e.duration&&e.duration>0?e.duration:Math.max(1,a-e.timestamp))/1e3}}),i=n.reduce((e,t)=>e+t.durationMs,0);n.some(e=>20!==e.durationMs)||i!==(t.endTimestampUs-t.startTimestampUs)/1e3?this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频")):(globalThis.clearTimeout(t.timeoutId),this.pendingEncode=null,t.resolve(n))}failPending(e){const t=this.pendingEncode;t&&(globalThis.clearTimeout(t.timeoutId),this.pendingEncode=null,t.reject(e))}}class v{constructor(e=16e3){this.chunks=[],this.hasHeader=!1,this.clusterTimestamp=0,this.frameDuration=100,this.sampleRate=e}writeHeader(){if(this.hasHeader)return;const e=this.buildEBMLHeader(),t=this.buildSegmentInfo(),n=this.buildOpusTracks();this.chunks.push(e),this.chunks.push(new Uint8Array([24,83,128,103,1,255,255,255,255,255,255,255])),this.chunks.push(t),this.chunks.push(n),this.hasHeader=!0,this.clusterTimestamp=0}feedOpusFrame(e,t=this.frameDuration){this.hasHeader||this.writeHeader();const n=this.buildCluster(Math.round(this.clusterTimestamp),e);this.chunks.push(n),this.clusterTimestamp+=t}flush(){if(0===this.chunks.length)return new ArrayBuffer(0);const e=this.chunks.reduce((e,t)=>e+t.length,0),t=new Uint8Array(e);let n=0;for(const e of this.chunks)t.set(e,n),n+=e.length;return this.chunks=[],t.buffer}reset(){this.chunks=[],this.hasHeader=!1,this.clusterTimestamp=0}encodeVINT(e,t){if(void 0!==t){const n=new Uint8Array(t);for(let i=t-1;i>=0;i--)n[i]=255&e,e>>>=8;return n[0]|=1<<8-t,n}if(e<127)return new Uint8Array([128|e]);if(e<16383)return new Uint8Array([64|e>>8,255&e]);if(e<2097151)return new Uint8Array([32|e>>16,e>>8&255,255&e]);if(e<268435455)return new Uint8Array([16|e>>24,e>>16&255,e>>8&255,255&e]);throw new Error(`VINT value too large: ${e}`)}encodeID(e){return e<=255?new Uint8Array([e]):e<=65535?new Uint8Array([e>>8,255&e]):e<=16777215?new Uint8Array([e>>16,e>>8&255,255&e]):new Uint8Array([e>>>24,e>>16&255,e>>8&255,255&e])}encodeUint(e){if(0===e)return new Uint8Array([0]);const t=[];let n=e;for(;n>0;)t.unshift(255&n),n=Math.floor(n/256);return new Uint8Array(t)}encodeString(e){return(new TextEncoder).encode(e)}encodeFloat32(e){const t=new ArrayBuffer(4);return new DataView(t).setFloat32(0,e,!1),new Uint8Array(t)}encodeElement(e,t){const n=this.encodeID(e),i=this.encodeVINT(t.length),s=new Uint8Array(n.length+i.length+t.length);return s.set(n,0),s.set(i,n.length),s.set(t,n.length+i.length),s}encodeUintElement(e,t){return this.encodeElement(e,this.encodeUint(t))}encodeStringElement(e,t){return this.encodeElement(e,this.encodeString(t))}encodeFloat32Element(e,t){return this.encodeElement(e,this.encodeFloat32(t))}concatArrays(e){const t=e.reduce((e,t)=>e+t.length,0),n=new Uint8Array(t);let i=0;for(const t of e)n.set(t,i),i+=t.length;return n}buildEBMLHeader(){const e=this.concatArrays([this.encodeUintElement(17030,1),this.encodeUintElement(17143,1),this.encodeUintElement(17138,4),this.encodeUintElement(17139,8),this.encodeStringElement(17026,"webm"),this.encodeUintElement(17031,4),this.encodeUintElement(17029,2)]);return this.encodeElement(440786851,e)}buildSegmentInfo(){const e=this.concatArrays([this.encodeUintElement(2807729,1e6),this.encodeStringElement(19840,"xmov-avatar-sdk"),this.encodeStringElement(22337,"xmov-avatar-sdk")]);return this.encodeElement(357149030,e)}buildOpusTracks(){const e=new Uint8Array([79,112,117,115,72,101,97,100,1,1,0,0,128,62,0,0,0,0,0]),t=this.concatArrays([this.encodeFloat32Element(181,this.sampleRate),this.encodeUintElement(159,1)]),n=this.concatArrays([this.encodeUintElement(215,1),this.encodeUintElement(29637,1),this.encodeUintElement(131,2),this.encodeUintElement(156,0),this.encodeStringElement(2274716,"und"),this.encodeStringElement(134,"A_OPUS"),this.encodeElement(25506,e),this.encodeUintElement(22186,0),this.encodeUintElement(22203,8e7),this.encodeElement(225,t)]),i=this.encodeElement(174,n);return this.encodeElement(374648427,i)}buildCluster(e,t){const n=this.encodeUintElement(231,e),i=this.encodeVINT(1),s=new Uint8Array([0,0]),r=new Uint8Array([128]),a=this.concatArrays([i,s,r,t]),o=this.encodeElement(163,a),l=this.concatArrays([n,o]);return this.encodeElement(524531317,l)}}class w{constructor(){this.opusEncoder=new y({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600}),this.muxer=new v(16e3),this.queue=Promise.resolve(),this.generation=0,this.destroyed=!1,this.pendingBlocks=0}static isSupported(){return y.isSupported()}async init(){await this.opusEncoder.init()}async encode(e){var t=this;if(1600!==e.length)throw new Error(`PCM 音频块必须为 1600 samples,实际为 ${e.length}`);if(this.pendingBlocks>=20)throw new Error("PCM/Opus 编码队列超过 2 秒");this.pendingBlocks+=1;const n=this.generation,i=new Int16Array(e),s=this.queue.then(async function(){if(t.destroyed||n!==t.generation)return new ArrayBuffer(0);const e=await t.opusEncoder.encode(i);if(t.destroyed||n!==t.generation)return new ArrayBuffer(0);for(const n of e)t.muxer.feedOpusFrame(n.data,n.durationMs);return t.muxer.flush()}).finally(()=>{this.pendingBlocks-=1});return this.queue=s.then(()=>{},()=>{}),s}reset(){const e=++this.generation;this.queue=this.queue.then(()=>{this.destroyed||e!==this.generation||(this.opusEncoder.reset(),this.muxer.reset())})}async destroy(){this.destroyed=!0,this.generation+=1,await this.opusEncoder.destroy(),await this.queue,this.muxer.reset()}}const _="audio/webm;codecs=opus",b=16e3,T="agent-pcm-capture-processor",k=`\nclass AgentPcmCaptureProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffer = new Float32Array(1600);\n this.bufferIndex = 0;\n this.sequence = 0;\n this.port.onmessage = (event) => {\n if (event.data?.type === 'flush') {\n this.emitBlock(true);\n this.port.postMessage({ type: 'flushed' });\n }\n };\n }\n\n emitBlock(padPartial = false) {\n if (this.bufferIndex === 0 || (!padPartial && this.bufferIndex < 1600)) return;\n const pcm = new Int16Array(1600);\n for (let index = 0; index < this.bufferIndex; index += 1) {\n const sample = Math.max(-1, Math.min(1, this.buffer[index]));\n pcm[index] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n }\n this.port.postMessage(\n { type: 'frame', pcm: pcm.buffer, sequence: this.sequence++ },\n [pcm.buffer],\n );\n this.buffer.fill(0);\n this.bufferIndex = 0;\n }\n\n process(inputs, outputs) {\n for (const output of outputs) {\n for (const channel of output) channel.fill(0);\n }\n const channels = inputs[0];\n if (!channels?.length || !channels[0]?.length) return true;\n for (let frame = 0; frame < channels[0].length; frame += 1) {\n let sample = 0;\n for (let channel = 0; channel < channels.length; channel += 1) {\n sample += channels[channel][frame] || 0;\n }\n this.buffer[this.bufferIndex++] = sample / channels.length;\n if (this.bufferIndex === 1600) this.emitBlock();\n }\n return true;\n }\n}\nregisterProcessor('${T}', AgentPcmCaptureProcessor);\n`;class C{constructor(e){var n,i;this.stream=null,this.recordingStream=null,this.audioTransformer=null,this.mediaRecorder=null,this.pcmAudioContext=null,this.pcmSource=null,this.pcmWorklet=null,this.pcmEncoder=null,this.pcmEncodeQueue=Promise.resolve(),this.pcmStartedAt=0,this.pcmGeneration=0,this.resolvePcmFlush=null,this.startGeneration=0,this.starting=!1,this.hasAudioSessionCapture=!1,this.options=e,this.pendingInputStream=null!=(n=e.inputStream)?n:null,this.usesProvidedInput=Boolean(e.inputStream),this.metadata=t({},l,{chunkMs:(null==(i=e.audio)?void 0:i.chunkMs)||l.chunkMs})}get isRecording(){return this.starting||Boolean(this.stream)||Boolean(this.pendingInputStream)}getAudioMetadata(){return this.metadata}async start(){if(this.stream||this.starting)return;const e=++this.startGeneration;this.starting=!0;try{var n,i;const a=this.pendingInputStream;this.stream=null!=a?a:null,this.pendingInputStream=null;const o=navigator.mediaDevices;if(!(this.stream||null!=o&&o.getUserMedia))throw new Error("当前浏览器不支持麦克风采集");const l=globalThis.MediaRecorder;if(this.options.usePcmWebCodecs){if(!await w.isSupported())throw this.webCodecsOpusUnsupported()}else if(null==l||null==l.isTypeSupported||!l.isTypeSupported(_))throw this.webMOpusUnsupported();if(this.assertStartActive(e),!this.stream){if(this.usesProvidedInput)throw a?this.cancelled():new Error("ASR 输入流已释放");this.hasAudioSessionCapture=function(e=navigator){var t,n;const i=g(e);if(!i)return!1;const s=p.get(i),r=null!=(t=null==s?void 0:s.previousType)?t:i.type;return!!E(i,"play-and-record")&&(p.set(i,{count:(null!=(n=null==s?void 0:s.count)?n:0)+1,previousType:r}),!0)}(),this.stream=await o.getUserMedia({audio:{sampleRate:{ideal:b},channelCount:{ideal:1},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}})}this.assertStartActive(e);const h=this.stream.getAudioTracks()[0];if(!h)throw new Error("麦克风未返回音频轨道");var s,r;if(this.options.usePcmWebCodecs)return await this.startPcmWebMRecorder(this.stream),this.assertStartActive(e),this.metadata=t({},this.metadata,{sampleRate:b,channels:1,chunkMs:100}),void(null==(s=(r=this.options).onMetadata)||s.call(r,this.metadata));const u=new c({onError:e=>{var t,n;const i=e instanceof Error?e:new Error("16 kHz mono 音频处理失败");i.name="MediaRecorderError",null==(t=(n=this.options).onError)||t.call(n,i)}});this.audioTransformer=u,this.recordingStream=await u.start(h),this.assertStartActive(e);const d=this.recordingStream.getAudioTracks()[0],m=null==d?void 0:d.getSettings();this.metadata=t({},this.metadata,{sampleRate:(null==m?void 0:m.sampleRate)||b,channels:(null==m?void 0:m.channelCount)||1}),this.startWebMRecorder(l),null==(n=(i=this.options).onMetadata)||n.call(i,this.metadata)}catch(t){const n=e!==this.startGeneration;await this.stop();const i=n?this.cancelled():t instanceof Error?t:new Error("麦克风启动失败");var a,o;throw"AUDIO_FIXED_TRACK_CANCELLED"!==i.agentCode&&(null==(a=(o=this.options).onError)||a.call(o,i)),i}finally{this.startGeneration===e&&(this.starting=!1)}}async stop(){this.startGeneration+=1,this.starting=!1;try{var e;const t=this.audioTransformer;try{await(null==t?void 0:t.drain())}finally{await this.stopPcmWebMRecorder(),await this.stopMediaRecorder(),await(null==t?void 0:t.stop()),this.audioTransformer=null}this.recordingStream=null,this.stream&&!t&&this.stream.getTracks().forEach(e=>e.stop()),this.stream=null,null==(e=this.pendingInputStream)||e.getTracks().forEach(e=>e.stop()),this.pendingInputStream=null}finally{this.hasAudioSessionCapture&&(this.hasAudioSessionCapture=!1,function(e=navigator){const t=g(e);if(!t)return!1;const n=p.get(t);if(!n)return function(e=navigator){const t=g(e);if(!t)return!1;const n=p.get(t);return E(t,null!=n&&n.count||"play-and-record"===t.type?"play-and-record":"playback")}(e);if(n.count-=1,n.count>0)return E(t,"play-and-record");p.delete(t);const i="play-and-record"===n.previousType?"play-and-record":"playback";E(t,i)&&"playback"===i&&function(e){const t=m.get(e);if(t)for(const e of[...t])try{e()}catch(e){}}(t)}())}}startWebMRecorder(e){if(!this.recordingStream)throw new Error("16 kHz mono 音频流未就绪");let t;try{t=new e(this.recordingStream,{mimeType:_,audioBitsPerSecond:24e3})}catch(e){if(e instanceof Error&&"NotSupportedError"===e.name)throw this.webMOpusUnsupported(e);throw e}const n=new S(this.metadata.chunkMs);t.ondataavailable=e=>{if(e.data.size>0){var i;const s=n.resolve(e.timecode);null==(i=globalThis.avatarSDKLogger)||null==i.log||i.log("[Agent][Microphone]","audio chunk",{size:e.data.size,type:e.data.type,chunkMs:this.metadata.chunkMs,sampleRate:this.metadata.sampleRate,channels:this.metadata.channels,recorderState:t.state,timecode:e.timecode}),this.options.debugAudioChunks&&d("[Agent][Microphone] nearend WebM/Opus chunk",e.data,{chunkMs:this.metadata.chunkMs,sampleRate:this.metadata.sampleRate,channels:this.metadata.channels,recorderState:t.state,timecode:e.timecode}),this.options.onFrame(e.data,s)}},t.onerror=e=>{var t,n;const i=e.error,s=new Error(i instanceof Error?i.message:"WebM/Opus 麦克风录制失败");s.name="MediaRecorderError",null==(t=(n=this.options).onError)||t.call(n,s)},this.mediaRecorder=t;try{t.start(this.metadata.chunkMs)}catch(e){if(e instanceof Error&&"NotSupportedError"===e.name)throw this.webMOpusUnsupported(e);throw e}}assertStartActive(e){if(e!==this.startGeneration)throw this.cancelled()}cancelled(){const e=new Error("麦克风启动已取消");return e.name="AbortError",e.agentCode="AUDIO_FIXED_TRACK_CANCELLED",e.retryable=!0,e}webMOpusUnsupported(e){const t=new Error("当前浏览器不支持 audio/webm;codecs=opus");return t.name="NotSupportedError",t.agentCode="AUDIO_WEBM_OPUS_UNSUPPORTED",t.retryable=!1,t.cause=e,t}webCodecsOpusUnsupported(e){const t=new Error("当前浏览器不支持 WebCodecs AudioEncoder Opus");return t.name="NotSupportedError",t.agentCode="AUDIO_WEBCODECS_OPUS_UNSUPPORTED",t.retryable=!1,t.cause=e,t}async startPcmWebMRecorder(e){var t=this;const n=globalThis,i=globalThis.AudioContext||n.webkitAudioContext;if(!i||void 0===globalThis.AudioWorkletNode)throw this.webCodecsOpusUnsupported(new Error("AudioWorklet 不可用"));const s=new w;await s.init();const r=new i({sampleRate:b});if(r.sampleRate!==b)throw await s.destroy(),await r.close().catch(()=>{}),this.webCodecsOpusUnsupported(new Error("浏览器无法创建 16000 Hz AudioContext"));this.pcmAudioContext=r,this.pcmEncoder=s;const a=URL.createObjectURL(new Blob([k],{type:"application/javascript"}));try{await r.audioWorklet.addModule(a)}finally{URL.revokeObjectURL(a)}if("suspended"===r.state&&await r.resume(),"running"!==r.state)throw this.audioContextSuspended();const o=r.createMediaStreamSource(e),l=new AudioWorkletNode(r,T,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[1]}),h=++this.pcmGeneration;this.pcmSource=o,this.pcmWorklet=l,this.pcmEncodeQueue=Promise.resolve(),this.pcmStartedAt=this.monotonicEpochNow(),l.port.onmessage=e=>{var n,i,r;if("flushed"===(null==(n=e.data)?void 0:n.type))return null==(r=this.resolvePcmFlush)||r.call(this),void(this.resolvePcmFlush=null);if("frame"!==(null==(i=e.data)?void 0:i.type)||!(e.data.pcm instanceof ArrayBuffer))return;const a=this.pcmStartedAt+100*Number(e.data.sequence||0),o=new Int16Array(e.data.pcm);this.pcmEncodeQueue=this.pcmEncodeQueue.then(async function(){const n=await s.encode(o);if(h!==t.pcmGeneration||0===n.byteLength)return;const i=new Blob([n],{type:_});t.options.debugAudioChunks&&d("[Agent][Microphone] nearend PCM/WebCodecs chunk",i,{chunkMs:100,sampleRate:b,channels:1,sequence:e.data.sequence}),t.options.onFrame(i,a)}).catch(e=>{var t,n;const i=e instanceof Error?e:new Error("PCM/Opus 麦克风编码失败");i.name="AudioEncoderError",null==(t=(n=this.options).onError)||t.call(n,i)})},o.connect(l),l.connect(r.destination)}async stopPcmWebMRecorder(){const e=this.pcmWorklet,t=this.pcmSource,n=this.pcmAudioContext,i=this.pcmEncoder;if(!e&&!n&&!i)return;null==t||t.disconnect();let s=!0;e&&(s=await Promise.race([new Promise(t=>{this.resolvePcmFlush=()=>t(!0),e.port.postMessage({type:"flush"})}),new Promise(e=>globalThis.setTimeout(()=>e(!1),100))]),s||(this.resolvePcmFlush=null,e.port.onmessage=null)),await this.pcmEncodeQueue,this.pcmGeneration+=1,this.resolvePcmFlush=null,e&&(e.port.onmessage=null,e.disconnect(),e.port.close()),n&&"closed"!==n.state&&await n.close().catch(()=>{}),await(null==i?void 0:i.destroy()),this.pcmWorklet=null,this.pcmSource=null,this.pcmAudioContext=null,this.pcmEncoder=null,this.pcmEncodeQueue=Promise.resolve()}monotonicEpochNow(){const e=globalThis.performance;return e&&Number.isFinite(e.timeOrigin)?Math.round(e.timeOrigin+e.now()):Date.now()}audioContextSuspended(){const e=new Error("AudioContext 未运行,请在用户操作后重试");return e.name="NotAllowedError",e.agentCode="AUDIO_CONTEXT_SUSPENDED",e.retryable=!0,e}async stopMediaRecorder(){const e=this.mediaRecorder;if(this.mediaRecorder=null,!e)return;const t="inactive"!==e.state;await new Promise(n=>{let i=!1;const s=()=>{i||(i=!0,globalThis.clearTimeout(a),n())},r=e.onerror,a=globalThis.setTimeout(s,1e3);if(e.onstop=s,e.onerror=t=>{null==r||r.call(e,t),s()},t)try{e.stop()}catch(e){s()}}),e.ondataavailable=null,e.onerror=null,e.onstop=null}}const O=new Uint8Array([26,69,223,163]);function D(e,t){const n=globalThis.avatarSDKLogger;null==n||null==n.log||n.log("[Agent][AudioUplink]",e,t)}function I(e,t,n){if(1!==e&&2!==e)throw new Error(`AU stream_id 无效: ${e}`);if(!Number.isFinite(t)||t<0||t>4294967295)throw new Error(`AU ts_ms 无效: ${t}`);const i=n instanceof ArrayBuffer?new Uint8Array(n):new Uint8Array(n.buffer,n.byteOffset,n.byteLength),s=new ArrayBuffer(8+i.byteLength),r=new DataView(s);return r.setUint8(0,65),r.setUint8(1,85),r.setUint8(2,1),r.setUint8(3,e),r.setUint32(4,Math.floor(t),!1),new Uint8Array(s,8).set(i),s}async function M(e){if(Array.isArray(e)){const t=await Promise.all(e.map(M)),n=new Uint8Array(t.reduce((e,t)=>e+t.byteLength,0));let i=0;for(const e of t)n.set(e,i),i+=e.byteLength;return n}return e instanceof Blob?new Uint8Array(await e.arrayBuffer()):e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}class P{constructor(e){this.connectionStartedAt=null,this.connectionGeneration=0,this.sendChain=Promise.resolve(),this.failed=!1,this.pendingFarend=new Map,this.pendingNearend=new Map,this.closedNearendBuckets=new Set,this.lastTimestampByStream=new Map,this.lastSentTimestampByStream=new Map,this.pendingWebmPrefixByStream=new Map,this.farendStreamState="unknown",this.options=e}reset(e=null){this.connectionGeneration+=1,this.connectionStartedAt=e,this.pendingFarend.clear(),this.pendingNearend.clear(),this.closedNearendBuckets.clear(),this.lastTimestampByStream.clear(),this.lastSentTimestampByStream.clear(),this.pendingWebmPrefixByStream.clear(),this.farendStreamState="unknown",this.failed=!1,this.sendChain=Promise.resolve()}startInput(){this.failed=!1,this.pendingFarend.clear(),this.pendingNearend.clear(),this.closedNearendBuckets.clear(),this.pendingWebmPrefixByStream.clear(),this.farendStreamState="unknown"}clearFarend(){this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="unknown"}offerFarend(e){var t;if(!1===e.isFirstChunk&&"ready"!==this.farendStreamState)return void D("farend.drop",{reason:"awaiting_webm_header",timestamp:e.timestamp,isFirstChunk:!1});const n=this.normalizeBlock(2,e);if(!n)return void(e.isFirstChunk&&this.abandonFarendStream());e.isFirstChunk&&(this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="ready");const i=null!=(t=this.pendingFarend.get(n.frameKey))?t:[];i.push(n),this.pendingFarend.set(n.frameKey,i),D("farend.offer",{tsMs:n.tsMs,frameKey:n.frameKey,isFirstChunk:Boolean(n.isFirstChunk),pendingNearend:[...this.pendingNearend.keys()]}),this.flushOlderNearend(n.frameKey),this.prune(n.frameKey)}offerNearend(e){var t;const n=this.normalizeBlock(1,e);if(!n||this.closedNearendBuckets.has(n.frameKey))return;const i=null!=(t=this.pendingNearend.get(n.frameKey))?t:[];i.push(n),this.pendingNearend.set(n.frameKey,i),this.flushExpiredNearend(n.frameKey),this.prune(n.frameKey)}drain(){for(const e of[...this.pendingNearend.keys()].sort((e,t)=>e-t))this.flushBucket(e,!0);return this.sendChain}normalizeBlock(e,n){const i=this.connectionStartedAt;if(null===i||!Number.isFinite(n.timestamp))return null;const s=Math.max(0,Math.floor(n.timestamp-i)),r=Math.floor(s/100),a=this.lastTimestampByStream.get(e);return void 0!==a&&s<=a?null:(this.lastTimestampByStream.set(e,s),t({},n,{streamId:e,tsMs:s,frameKey:r}))}enqueue(e){var t=this;if(this.failed)return;const n=this.connectionGeneration;this.sendChain=this.sendChain.then(async function(){if(!t.failed)for(const s of e){var i;const e=await M(null!=(i=s.dataParts)?i:s.data);if(t.failed||n!==t.connectionGeneration||null===t.connectionStartedAt||0===e.byteLength)continue;2===s.streamId&&s.isFirstChunk&&t.pendingWebmPrefixByStream.delete(2);const r=t.coalesceSplitWebmMagic(s.streamId,e);if(!r)continue;const a=t.lastSentTimestampByStream.get(s.streamId);void 0!==a&&s.tsMs<=a||(t.options.sendBinary(I(s.streamId,s.tsMs,r)),t.lastSentTimestampByStream.set(s.streamId,s.tsMs),D("frame.send",{streamId:s.streamId,tsMs:s.tsMs,bytes:r.byteLength}))}}).catch(e=>{var t,i;if(n!==this.connectionGeneration)return;this.failed=!0,this.pendingFarend.clear(),this.pendingNearend.clear();const s=e instanceof Error?e:new Error("AU 音频上行失败");null==(t=(i=this.options).onError)||t.call(i,s)})}coalesceSplitWebmMagic(e,t){const n=this.pendingWebmPrefixByStream.get(e);if(n){const i=new Uint8Array(n.byteLength+t.byteLength);i.set(n),i.set(t,n.byteLength),this.pendingWebmPrefixByStream.delete(e),t=i}return t.byteLength<O.byteLength&&t.every((e,t)=>e===O[t])?(this.pendingWebmPrefixByStream.set(e,t.slice()),null):t}flushOlderNearend(e){for(const t of[...this.pendingNearend.keys()].sort((e,t)=>e-t)){if(t>=e)break;this.flushBucket(t,!0)}}flushExpiredNearend(e){this.flushOlderNearend(e-1)}flushBucket(e,t=!1){const n=this.takeNearend(e);if(!n)return;const i=e-1,s=this.pendingFarend.has(e)||t&&this.pendingFarend.has(i)?this.takeFarendThrough(e):null;this.closedNearendBuckets.add(e),D("bucket.flush",{nearendFrameKey:e,pairedFarend:Boolean(s),pendingFarend:[...this.pendingFarend.keys()]}),this.enqueue(s?[s,n]:[n])}takeNearend(e){const n=this.pendingNearend.get(e);return this.pendingNearend.delete(e),null!=n&&n.length?t({},n[0],{dataParts:n.flatMap(e=>{var t;return null!=(t=e.dataParts)?t:[e.data]})}):null}takeFarendThrough(e){const n=[];for(const t of[...this.pendingFarend.keys()].sort((e,t)=>e-t)){if(t>e)break;n.push(...this.pendingFarend.get(t)),this.pendingFarend.delete(t)}return 0===n.length?null:t({},n[n.length-1],{dataParts:n.map(e=>e.data),isFirstChunk:n.some(e=>e.isFirstChunk)})}abandonFarendStream(){D("farend.drop",{reason:"stale_bucket_abandons_webm_stream",pendingFarend:[...this.pendingFarend.keys()]}),this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="awaiting-header"}prune(e){const t=e-3;[...this.pendingFarend.keys()].some(e=>e<t)&&this.abandonFarendStream();for(const e of this.pendingNearend.keys())e<t&&this.flushBucket(e,!0);for(const e of this.closedNearendBuckets)e<t&&this.closedNearendBuckets.delete(e)}}const N=["e2eServer","authToken","audio","reconnect","agentCallbacks","webSocketCtor","asr_id","asr_config","tts_config","features","extras","llm_id","brain_config","session_speak_req_id"],F=2147483647;function U(e){if(void 0===e)return!1;const t=JSON.stringify(e);return void 0!==t&&"{}"!==t}const B={1006:"E2E WebSocket 异常断开:未收到 Close frame,请检查 E2EMPServer 日志或中间网络",4e3:"E2E WebSocket 路径未知",4001:"E2E Token 无效",4002:"E2E Session 不存在",4009:"E2E 配额超限",4010:"E2E 服务端主动断开"},x=new Set([1001,1006,1011,1012,1013,1014]);function W(e,t,n){if(void 0!==n&&(!n||Array.isArray(n)||"object"!=typeof n))throw new Error(`Agent ${e} JSON Config 必须是对象`);if(void 0!==t&&U(n))throw new Error(`Agent ${e} 配置不能同时提供 ID 和 JSON Config`)}function L(e,t){if(void 0!==t&&(!t||Array.isArray(t)||"object"!=typeof t))throw new Error(`Agent ${e} 必须是对象`)}class G extends e{constructor(e){var n,i,s;W("ASR",e.asr_id,e.asr_config),W("TTS",void 0,e.tts_config),W("Brain",e.llm_id,e.brain_config),L("features",e.features),L("extras",e.extras);const{e2eServer:r,authToken:a,audio:o,reconnect:l,agentCallbacks:h,webSocketCtor:c,asr_id:u,asr_config:d,tts_config:p,features:m,extras:g,llm_id:E,brain_config:f,session_speak_req_id:S}=e,R=function(e,t){if(null==e)return{};var n={};for(var i in e)if({}.hasOwnProperty.call(e,i)){if(-1!==t.indexOf(i))continue;n[i]=e[i]}return n}(e,N),A=R.onMessage,y=R.onRenderChange,v=R.onNetworkInfo,w=R.onSpeakStateChange,_=R.onVoiceStateChange,b=R.onAudioPlaybackData,T=e=>{var t;null==(t=O)||t.forwardFarendAudio(e),null==b||b(e)},k=null!=S?S:1,C=function(e){if(!e||!U(e))return;const n=e.extra_body;if(void 0!==n&&(!n||Array.isArray(n)||"object"!=typeof n))throw new Error("Agent Brain extra_body 必须是 JSON 对象");return t({},e)}(f);let O;super(t({},R,{session_speak_req_id:k,sessionRequestData:t({},void 0!==u?{asr_id:u}:{},U(d)?{asr_config:d}:{},U(p)?{tts_config:p}:{},U(m)?{features:m}:{},U(g)?{extras:g}:{},void 0!==E?{llm_id:E}:{},void 0!==C?{brain_config:C}:{},{session_speak_req_id:k}),enableClientInterrupt:null==(n=R.enableClientInterrupt)||n,onMessage:e=>{var t,n;A(e),null!=(t=O)&&t.reportingInitializationFailure||null==(n=O)||n.emitError("sdk",String(e.code||"AVATAR_ERROR"),e.message||"Avatar SDK 错误",!0,e)},onRenderChange:e=>{var t;null==y||y(e),null==(t=O)||t.safeEmit(()=>null==h||null==h.onRenderChange?void 0:h.onRenderChange(e))},onNetworkInfo:e=>{var t;null==v||v(e),null==(t=O)||t.safeEmit(()=>null==h||null==h.onNetworkInfo?void 0:h.onNetworkInfo(e))},onSpeakStateChange:(e,t)=>{var n,i,s;null==w||w(e,t),null==(n=O)||n.safeEmit(()=>null==h||null==h.onSpeakStateChange?void 0:h.onSpeakStateChange({state:e,clientSpeakId:t})),["speak_start","start","started"].includes(e)&&(O&&(O.interactionPending=!0,O.voicePlaying=!0),null==(i=O)||i.emitConversation({state:"speaking"})),["speak_end","end","ended","completed","finish","finished"].includes(e)&&(null==(s=O)||s.emitConversation({state:"completed"}))},onVoiceStateChange:(e,t,n)=>{var i;O&&"start"===e&&(O.voicePlaying=!0),"end"===e&&(O&&(O.voicePlaying=!1),null==(i=O)||i.forwardVoiceEnd()),null==_||_(e,t,n)}},b?{onAudioPlaybackData:T}:{})),this.e2eClient=null,this.microphone=null,this.stopASRPromise=null,this.initializationPromise=null,this.rejectInitialization=null,this.initialSessionAttempt=null,this.initialSessionGeneration=0,this.initialTtsaReadySessionIds=new Set,this.initialTtsaReadyBeforeSession=!1,this.asrStartGeneration=0,this.agentState="idle",this.asrState="idle",this.agentDestroyed=!1,this.agentDestroying=!1,this.destroyPromise=null,this.suppressNextVoiceEnd=!1,this.replaySending=!1,this.farendAudioEnabled=!1,this.reconnectTimer=null,this.reconnectAttempt=0,this.reconnectInFlight=!1,this.sessionReloadFallback=!1,this.waitingForTtsaReload=!1,this.stateBeforeReconnect="ready",this.e2eSessionId="",this.currentE2EUrl="",this.serviceReconnect=null,this.serviceMigration=null,this.interactionPending=!1,this.llmPending=!1,this.llmProducedText=!1,this.directSpeakOpen=!1,this.pendingASR=!1,this.autoSendASRToLLM=!0,this.voicePlaying=!1,this.reportingInitializationFailure=!1,this.handleOnlineForReconnect=()=>{this.serviceMigration||"reconnecting"!==this.agentState||this.reconnectInFlight||this.sessionReloadFallback||(this.clearReconnectTimer(),this.scheduleE2EReconnect(!0))},O=this,this.agentOptions={e2eServer:r,authToken:a,audio:o,requestedEnableAec:"boolean"==typeof(null==m||null==(i=m.speech_frontend)?void 0:i.enable_aec)?m.speech_frontend.enable_aec:void 0,callbacks:h,webSocketCtor:c,debugAudioChunks:Boolean(R.enableDebugger)},this.audioInputEnabled=null!=(s=null==o?void 0:o.inputEnabled)&&s,this.autoSendASRToLLM=!1!==(null==m?void 0:m.auto_send_asr_to_llm),this.originalOnAudioPlaybackData=b,this.playbackDataHandler=T,this.reconnectOptions=this.normalizeReconnectOptions(l),this.audioUplink=new P({sendBinary:e=>{var t;return null==(t=this.e2eClient)?void 0:t.sendBinary(e)},onError:e=>this.handleAudioUplinkError(e)})}getAgentState(){return this.agentState}getState(){return this.getAgentState()}getASRState(){return this.asrState}init(e={}){if(this.initializationPromise)return this.initializationPromise;const t=this.initialize(e).finally(()=>{this.initializationPromise===t&&(this.initializationPromise=null)});return this.initializationPromise=t,t}async initialize(e){this.assertNotDestroyed(),this.setAgentState("initializing");const n=new Promise((e,t)=>{this.rejectInitialization=t});n.catch(()=>{});try{const i=t({},e,{onDownloadProgress:e.onDownloadProgress||(()=>{})}),s=await super.initializeSession(i);if(this.assertNotDestroyed(),!s)throw new Error("XmovAvatar 初始化未返回 sessionInfo");for(this.applySessionFeatures(s),this.assertNotDestroyed(),this.beginInitialSession(s);;){const e=this.initialSessionAttempt;if(!e)throw new Error("Agent 初始化缺少会话连接任务");if(await Promise.race([Promise.all([e.e2ePromise,e.ttsaReadyPromise]),n]),e===this.initialSessionAttempt)break}for(this.assertNotDestroyed();this.serviceMigration;)await this.serviceMigration.completion;this.assertE2EOpen(),this.setAgentState("ready"),this.start()}catch(e){if(this.serviceMigration&&!this.agentDestroying&&!this.agentDestroyed)throw this.failServiceMigration("E2E_MIGRATION_FAILED","E2E 更新迁移失败"),e;if(!this.agentDestroyed&&!this.agentDestroying){var i;null==(i=this.e2eClient)||i.disconnect(1e3,"agent_init_failed"),this.e2eClient=null,await this.cleanupBeforeInitComplete("agent_init_failed");try{this.setAgentState("failed")}catch(e){}this.reportingInitializationFailure=!0;try{this.reportInitializationFailure("Agent 初始化失败",e)}catch(e){}finally{this.reportingInitializationFailure=!1}try{this.emitError("sdk","AGENT_INIT_FAILED","Agent 初始化失败",!0,e)}catch(e){}this.agentDestroyed=!0}throw e}finally{var s;this.rejectInitialization=null,this.initialSessionGeneration+=1,null==(s=this.initialSessionAttempt)||s.resolveTtsaReady(),this.initialSessionAttempt=null,this.initialTtsaReadySessionIds.clear(),this.initialTtsaReadyBeforeSession=!1}}beginInitialSession(e){this.e2eSessionId=e.session_id;const t=this.initialSessionAttempt,n=++this.initialSessionGeneration;null==t||t.resolveTtsaReady();let i=()=>{};const s=new Promise(e=>{i=e}),r=this.replaceE2EConnection(e.e2e_resp).catch(e=>{if(n===this.initialSessionGeneration)throw e}),a={sessionInfo:e,e2ePromise:r,ttsaReadyPromise:s,resolveTtsaReady:i};return this.initialSessionAttempt=a,this.initialTtsaReadySessionIds.delete(e.session_id)?a.resolveTtsaReady():!t&&this.initialTtsaReadyBeforeSession&&(this.initialTtsaReadyBeforeSession=!1,a.resolveTtsaReady()),r.catch(()=>{}),r}start(){var e;"initializing"!==this.agentState&&"running"!==this.agentState&&("reconnecting"!==this.agentState?(this.assertE2EOpen(),super.start(),this.setAgentState("running")):this.waitingForTtsaReload&&null!=(e=this.e2eClient)&&e.isOpen&&("running"===this.stateBeforeReconnect&&super.start(),this.finishReconnect()))}onTtsaReady(e){if(this.rejectInitialization){const t=this.initialSessionAttempt,n=null==e?void 0:e.session_id;!t||n&&t.sessionInfo.session_id!==n?n?this.initialTtsaReadySessionIds.add(n):this.initialTtsaReadyBeforeSession=!0:t.resolveTtsaReady()}else"reconnecting"!==this.agentState?"running"===this.agentState&&super.start():this.start()}abortInitialization(e){var t;null==(t=this.rejectInitialization)||t.call(this,e)}async stop(){if(this.agentDestroyed)return;const e="reconnecting"===this.agentState;e&&(this.stateBeforeReconnect="stopped",this.serviceMigration&&(this.serviceMigration.previousState="stopped")),await this.stopASR(),await super.stop(),e||this.setAgentState("stopped")}async switchInvisibleMode(){const e=this.getStatus(),t=e===i.online||e===i.visible;super.switchInvisibleMode(),t&&await this.stopASR()}destroy(e="js_sdk_exit"){return this.destroyPromise?this.destroyPromise:this.agentDestroyed?("destroyed"!==this.agentState&&this.setAgentState("destroyed"),Promise.resolve()):(this.agentDestroying=!0,this.destroyPromise=Promise.resolve().then(()=>this.finishDestroy(e)),this.destroyPromise)}async finishDestroy(e){this.abortInitialization(new Error("Agent 初始化已取消")),this.cancelServiceMigration(),this.serviceReconnect=null,this.cancelReconnect(),this.cancelSessionRestart();try{await this.stopASR()}catch(e){this.emitError("sdk","AGENT_ASR_STOP_FAILED","Agent 销毁时停止 ASR 失败",!1,e)}const t=this.e2eClient;try{await(null==t?void 0:t.disconnectAndWait(1e3,e))}finally{this.e2eClient===t&&(this.e2eClient=null),this.audioUplink.reset()}try{await this.disconnectClientForDestroy(e)}finally{this.agentDestroyed=!0,this.agentDestroying=!1,this.setAgentState("destroyed")}}async ask(e){this.assertRunning(),this.interactionPending=!0,this.llmPending=!0,this.llmProducedText=!1,this.suppressNextVoiceEnd=!1,this.emitConversation({state:"asking",text:e}),this.sendControl({type:"ask",message:{text:e}})}speak(e,t=!0,n=!0){var i;if(this.replaySending)return n&&(this.suppressNextVoiceEnd=!0),super.speak(e,t,n,arguments[3]);"draining"===(null==(i=this.serviceMigration)?void 0:i.phase)&&this.directSpeakOpen&&!t?this.assertE2EOpen():this.assertRunning(),this.interactionPending=!0,this.directSpeakOpen=!n,this.suppressNextVoiceEnd=!1,t&&this.emitConversation({state:"speaking-directly",text:e}),this.sendControl({type:"speak",message:{text:e,is_start:t,is_end:n}})}handleReplaySend(e){if(this.serviceMigration)return;const t=this.replaySending;this.replaySending=!0;try{super.handleReplaySend(e)}finally{this.replaySending=t}}async speakByE2E(e){this.speak(e)}async startASR(e={}){var t;if(this.assertASRStartAllowed(),this.suppressNextVoiceEnd=!1,this.stopASRPromise&&(await this.stopASRPromise,this.assertASRStartAllowed()),null!=(t=this.microphone)&&t.isRecording)return;this.assertAudioChunkDuration();const n=e.inputStream?this.cloneASRInputStream(e.inputStream):void 0,i=++this.asrStartGeneration,s=!this.audioInputEnabled,r=new C({audio:this.agentOptions.audio,debugAudioChunks:this.agentOptions.debugAudioChunks,inputStream:n,usePcmWebCodecs:this.farendAudioEnabled,onFrame:(e,t)=>{var n,i;if(("running"===this.agentState||"draining"===(null==(n=this.serviceMigration)?void 0:n.phase))&&null!=(i=this.e2eClient)&&i.isOpen)try{var s;this.sendAudioFrame({data:e,timestamp:null!=t?t:Date.now()-((null==(s=this.agentOptions.audio)?void 0:s.chunkMs)||l.chunkMs)})}catch(e){this.stopASRAfterSocketClose()}},onError:e=>this.handleMicrophoneError(r,e)});this.microphone=r;try{this.audioUplink.startInput(),s&&this.enableAudioInput(),this.emitConversation({state:"asking"}),this.assertASRStartActive(i),this.setASRState("requesting-permission"),this.assertASRStartActive(i),this.setASRState("starting"),this.assertASRStartActive(i),await r.start(),this.assertRunning(),this.farendAudioEnabled&&this.restartAudioPlaybackCapture(),this.setASRState("listening")}catch(e){var a,o;await r.stop();const t="AUDIO_FIXED_TRACK_CANCELLED"===(null==e?void 0:e.agentCode),n=i===this.asrStartGeneration,l=!this.agentDestroyed&&!this.agentDestroying&&"running"===this.agentState&&Boolean(null==(a=this.e2eClient)?void 0:a.isOpen);if(this.microphone===r&&(this.microphone=null),n&&!t&&s&&null!=(o=this.e2eClient)&&o.isOpen)try{this.disableAudioInput()}catch(e){}throw!n||this.agentDestroyed||this.agentDestroying||(t&&l?this.setASRState("idle"):t||this.setASRState("failed")),t&&!l&&this.assertRunning(),e}}cloneASRInputStream(e){const t=e.getAudioTracks().find(e=>"ended"!==e.readyState);if(!t)throw new Error("ASR 输入流不包含有效音频轨道");return new MediaStream([t.clone()])}assertASRStartActive(e){if(e===this.asrStartGeneration)return;const t=new Error("麦克风启动已取消");throw t.name="AbortError",t.agentCode="AUDIO_FIXED_TRACK_CANCELLED",t.retryable=!0,t}stopASR(){if(this.asrStartGeneration+=1,this.stopASRPromise)return this.stopASRPromise;const e=this.microphone;var t;return null!=e&&e.isRecording?(this.microphone=null,this.stopASRPromise=this.finishStopASR(e).finally(()=>{this.stopASRPromise=null}),this.stopASRPromise):(null!=(t=this.e2eClient)&&t.isOpen&&this.disableAudioInput(),Promise.resolve())}async finishStopASR(e,t=!0){this.setASRState("stopping"),await e.stop(),await this.audioUplink.drain(),t?(this.disableAudioInput(),this.setASRState("idle")):this.setASRState("failed")}interrupt(){if(this.agentDestroyed||this.agentDestroying||this.serviceMigration&&"draining"!==this.serviceMigration.phase)return 0;this.sendControl({type:"interrupt"});const e=super.interrupt("speak");return this.interactionPending=!1,this.llmPending=!1,this.llmProducedText=!1,this.directSpeakOpen=!1,this.pendingASR=!1,this.voicePlaying=!1,this.emitConversation({state:"interrupted"}),this.checkServiceMigration(),e}async interruptConversation(e="user"){this.interrupt()}async onSessionReloaded(e){if(!this.agentDestroyed&&!this.agentDestroying){if(this.cancelServiceMigration(),this.serviceReconnect=null,this.e2eSessionId=e.session_id,this.rejectInitialization)return this.applySessionFeatures(e),void await this.beginInitialSession(e);"reconnecting"!==this.agentState&&(this.stateBeforeReconnect=this.readRestorableState(),this.setAgentState("reconnecting")),this.clearReconnectTimer(),this.sessionReloadFallback=!0,this.applySessionFeatures(e),await this.replaceE2EConnection(e.e2e_resp),this.waitingForTtsaReload=!0,this.sessionReloadFallback=!1}}onSessionReloadExhausted(e){this.rejectInitialization?this.abortInitialization(e instanceof Error?e:new Error("Agent 初始化期间 TTSA Session 恢复失败")):"reconnecting"===this.agentState&&this.failReconnect(e)}async replaceE2EConnection(e,t=!0){const{wsUrl:n,token:i}=this.resolveE2EConnection(e);this.currentE2EUrl=n;const s=this.e2eClient;let r;this.audioUplink.reset(),r=new o({wsUrl:n,token:i,audioInputEnabled:this.audioInputEnabled,WebSocketCtor:this.agentOptions.webSocketCtor,onStateChange:e=>{this.e2eClient===r&&("open"===e&&this.audioUplink.reset(Date.now()),this.safeEmit(()=>{var t;return null==(t=this.agentOptions.callbacks)||null==t.onSocketStateChange?void 0:t.onSocketStateChange(e)}))},onEvent:e=>{var t,n;this.e2eClient===r&&"closing"!==(null==(t=this.serviceMigration)?void 0:t.phase)&&"failed"!==(null==(n=this.serviceMigration)?void 0:n.phase)&&this.handleServerEvent(e)},onError:e=>{this.e2eClient===r&&"initializing"!==this.agentState&&"reconnecting"!==this.agentState&&this.emitError("network","E2E_SOCKET_ERROR",e.message,!0,e)},onClose:e=>{this.e2eClient===r&&this.handleSocketClose(e)}}),this.e2eClient=r,null==s||s.disconnect(1e3,"e2e_connection_replaced"),t&&await r.connect()}resolveE2EConnection(e){const t=Boolean(null==e?void 0:e.ws_url),n=Boolean(null==e?void 0:e.e2e_token);if(t!==n)throw new Error("统一 session 响应的 e2e_resp 必须同时返回 ws_url 和 e2e_token");if(t&&n)return{wsUrl:null==e?void 0:e.ws_url,token:null==e?void 0:e.e2e_token};const i=Boolean(this.agentOptions.e2eServer);if(i!==Boolean(this.agentOptions.authToken))throw new Error("e2eServer 和 authToken 必须同时配置");if(!i)throw new Error("统一 session 响应未返回 e2e_resp.ws_url,且未配置 e2eServer");return{wsUrl:this.agentOptions.e2eServer,token:this.agentOptions.authToken}}sendControl(e){try{var t;null==(t=this.e2eClient)||t.send(e)}catch(e){throw this.emitError("network","E2E_SEND_FAILED","E2E WebSocket 发送失败",!0,e),e}}assertAudioChunkDuration(){var e;const t=(null==(e=this.agentOptions.audio)?void 0:e.chunkMs)||l.chunkMs;if(!this.farendAudioEnabled||t===l.chunkMs)return;const n=new Error("AU v1 音频分片固定为 100ms");throw n.name="NotSupportedError",n.agentCode="AUDIO_CHUNK_DURATION_UNSUPPORTED",n.retryable=!1,this.emitError("sdk",n.agentCode,n.message,n.retryable,n),n}sendAudioFrame(e){if(this.farendAudioEnabled)this.agentOptions.debugAudioChunks&&d("[Agent][E2E] nearend AU chunk",e.data,{timestamp:e.timestamp,stream_id:1}),this.audioUplink.offerNearend(e);else{this.agentOptions.debugAudioChunks&&d("[Agent][E2E] nearend raw WebM/Opus chunk",e.data,{timestamp:e.timestamp});try{var t;null==(t=this.e2eClient)||t.sendBinary(e.data)}catch(e){this.handleAudioUplinkError(e instanceof Error?e:new Error("E2E nearend 音频帧发送失败"))}}}handleAudioUplinkError(e){this.emitError("network","E2E_AUDIO_SEND_FAILED",this.farendAudioEnabled?"E2E AU 音频帧发送失败":"E2E 音频帧发送失败",!0,e);const t=this.microphone;if(null==t||!t.isRecording||this.stopASRPromise)return;this.setASRState("failed"),this.microphone=null;const n=this.finishFailedASR(t).finally(()=>{this.stopASRPromise===n&&(this.stopASRPromise=null)});this.stopASRPromise=n}applySessionFeatures(e){var t,n,i,s,r,a,o,l,h;const c=null!=(t=null==(n=e.e2e_resp)||null==(n=n.features)?void 0:n.auto_send_asr_to_llm)?t:null==(i=e.features)?void 0:i.auto_send_asr_to_llm;"boolean"==typeof c&&(this.autoSendASRToLLM=c);const u=null!=(s=null==(r=e.e2e_resp)||null==(r=r.features)||null==(r=r.speech_frontend)?void 0:r.enable_aec)?s:null==(a=e.features)||null==(a=a.speech_frontend)?void 0:a.enable_aec;if(this.farendAudioEnabled="boolean"==typeof u?u:null!=(o=null!=(l=this.agentOptions.requestedEnableAec)?l:null==(h=this.agentOptions.audio)?void 0:h.echoCancellationEnabled)&&o,this.farendAudioEnabled||this.audioUplink.clearFarend(),this.farendAudioEnabled||this.originalOnAudioPlaybackData)return this.setAudioPlaybackDataHandler(this.playbackDataHandler),void(this.farendAudioEnabled&&this.enableAudioPlaybackCapture());this.setAudioPlaybackDataHandler(void 0)}forwardFarendAudio(e){var t,n;const i=Boolean(null==(t=this.microphone)?void 0:t.isRecording),s=Boolean(null==(n=this.e2eClient)?void 0:n.isOpen);var r;this.farendAudioEnabled&&i&&s?(this.agentOptions.debugAudioChunks&&d("[Agent][E2E] farend AU chunk",e.data,{timestamp:e.timestamp,stream_id:2,codec:e.codec,sampleRate:e.sampleRate,channels:1,samples:e.samples,speech_id:e.speech_id,isFirstChunk:e.isFirstChunk}),this.audioUplink.offerFarend({data:e.data,timestamp:e.timestamp,isFirstChunk:e.isFirstChunk})):null==(r=globalThis.avatarSDKLogger)||null==r.log||r.log("[Agent][AudioUplink]","farend.drop",{reason:this.farendAudioEnabled?i?"e2e_not_open":"microphone_not_recording":"aec_disabled",timestamp:e.timestamp,isFirstChunk:e.isFirstChunk})}handleMicrophoneError(e,t){var n;const i=t,s="MediaRecorderError"===t.name,r="AudioEncoderError"===t.name,a=s||r,o="NotSupportedError"===t.name,l=Boolean(i.agentCode);if(a&&this.microphone===e&&"stopping"!==this.asrState){this.microphone=null;const t=this.finishFailedASR(e).finally(()=>{this.stopASRPromise===t&&(this.stopASRPromise=null)});this.stopASRPromise=t}this.emitError(a?"asr":l||o?"sdk":"permission",i.agentCode||(s?"MEDIA_RECORDER_ERROR":r?"AUDIO_ENCODER_ERROR":"MICROPHONE_ERROR"),t.message,null!=(n=i.retryable)?n:!o,t)}async finishFailedASR(e){try{await e.stop(),await this.audioUplink.drain()}catch(e){this.emitError("sdk","MICROPHONE_CLEANUP_FAILED","麦克风异常后的资源清理失败",!1,e)}try{this.disableAudioInput()}catch(e){}}enableAudioInput(){var e;this.audioInputEnabled||(this.sendControl({type:"event",message:"audio_input_on"}),this.audioInputEnabled=!0,null==(e=this.e2eClient)||e.setAudioInputEnabled(!0))}disableAudioInput(){var e;this.audioInputEnabled&&(this.sendControl({type:"event",message:"audio_input_off"}),this.audioInputEnabled=!1,null==(e=this.e2eClient)||e.setAudioInputEnabled(!1))}handleServerEvent(e){var t;if(!this.agentDestroyed&&!this.agentDestroying)switch(e.type){case"service_update":return void this.handleServiceUpdate(e);case"pong":default:return;case"asr_result":return void this.handleASRResult(e);case"llm_response":return void this.handleLLMResponse(e);case"semantic_judge_round_result":return void this.handleSemanticJudgeResult(e);case"volume_and_repetition_text_response":return void(!0===(null==(t=e.message)?void 0:t.skip)&&(this.pendingASR=!1,this.checkServiceMigration()));case"error":return void this.handleBackendError(e)}}handleASRResult(e){this.autoSendASRToLLM&&(this.pendingASR="string"==typeof e.text&&Boolean(e.text.trim()));const t={text:"string"==typeof e.text?e.text:"",isFinal:!0===e.is_final,raw:e};this.safeEmit(()=>{var e;return null==(e=this.agentOptions.callbacks)||null==e.onASRResult?void 0:e.onASRResult(t)}),this.checkServiceMigration()}handleLLMResponse(e){if("chunk"!==e.event&&"done"!==e.event)return;this.llmPending="done"!==e.event,this.pendingASR=!1,"chunk"===e.event&&e.text&&(this.interactionPending=!0,this.llmProducedText=!0),"done"===e.event&&(this.llmProducedText||(this.interactionPending=!1),this.llmProducedText=!1);const n=e.usage,i=t({event:e.event},"string"==typeof e.text?{text:e.text}:{},!0===e.is_first?{isFirst:!0}:{},n?{usage:{promptTokens:this.readFiniteNumber(n.prompt_tokens),completionTokens:this.readFiniteNumber(n.completion_tokens),totalTokens:this.readFiniteNumber(n.total_tokens),cachedTokens:this.readFiniteNumber(n.cached_tokens)}}:{},{raw:e});this.safeEmit(()=>{var e;return null==(e=this.agentOptions.callbacks)||null==e.onLLMResponse?void 0:e.onLLMResponse(i)}),this.checkServiceMigration()}handleSemanticJudgeResult(e){if(!e.message||"object"!=typeof e.message)return;const t=e.message,n={query:"string"==typeof t.query?t.query:"",meaningful:!0===t.meaningful,action:"string"==typeof t.action?t.action:"",raw:e};this.safeEmit(()=>{var e;return null==(e=this.agentOptions.callbacks)||null==e.onSemanticJudgeResult?void 0:e.onSemanticJudgeResult(n)}),!1===t.meaningful&&(this.pendingASR=!1,this.checkServiceMigration())}forwardVoiceEnd(){var e,t;if(this.suppressNextVoiceEnd)return this.suppressNextVoiceEnd=!1,this.interactionPending=!1,void this.checkServiceMigration();if(!(this.agentDestroyed||this.agentDestroying||"running"!==this.agentState&&"draining"!==(null==(e=this.serviceMigration)?void 0:e.phase)||null==(t=this.e2eClient))&&t.isOpen)try{this.sendControl({type:"event",message:"voice_end"}),this.interactionPending=!1,this.checkServiceMigration()}catch(e){}}readFiniteNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:0}handleBackendError(e){var t;const n=["permission","network","asr","brain","ttsa","quota","sdk"].includes(e.domain)?e.domain:"sdk",i=String(null!=(t=e.code)?t:"BACKEND_ERROR"),s="string"==typeof e.message?e.message:"E2E 后端错误";"asr"===n&&(this.stopASRAfterSocketClose(),this.pendingASR=!1),"brain"===n&&(this.pendingASR=!1,this.llmPending=!1,this.llmProducedText||(this.interactionPending=!1)),this.emitConversation({state:"failed"}),this.emitError(n,i,s,"quota"!==n,e),this.checkServiceMigration()}handleServiceUpdate(e){var t;if(this.serviceMigration&&("connecting"!==this.serviceMigration.phase||null==(t=this.e2eClient)||!t.isOpen))return;let n=null;const i=e.grace_period_ms;try{const t=e.reconnect;if(!t||"string"!=typeof t.ws_url||"string"!=typeof t.e2e_token||!t.e2e_token||t.session_id!==this.e2eSessionId||"number"!=typeof i||!Number.isSafeInteger(i)||i<0||i>F||"number"!=typeof t.expires_in_ms||!Number.isSafeInteger(t.expires_in_ms)||t.expires_in_ms<=0||t.expires_in_ms>F)throw new Error("Invalid migration payload");const s=new URL(t.ws_url);if(!["ws:","wss:"].includes(s.protocol)||s.username||s.password||s.hash||this.currentE2EUrl.startsWith("wss:")&&"wss:"!==s.protocol||1!==s.searchParams.getAll("session_id").length||s.searchParams.get("session_id")!==this.e2eSessionId||1!==s.searchParams.getAll("token").length||s.searchParams.get("token")!==t.e2e_token)throw new Error("Invalid migration URL");n={session_id:this.e2eSessionId,ws_url:t.ws_url,e2e_token:t.e2e_token,expiresAt:Date.now()+t.expires_in_ms,attempts:0}}catch(e){return void(this.serviceMigration?this.failServiceMigration("E2E_SERVICE_UPDATE_INVALID","服务更新缺少有效的同房重连凭据"):this.startServiceMigration(null,0))}this.serviceMigration&&(this.stateBeforeReconnect=this.serviceMigration.previousState,this.cancelServiceMigration()),this.serviceReconnect=n,this.startServiceMigration(n,i)}startServiceMigration(e,t){var n;if(this.serviceMigration||this.agentDestroyed||this.agentDestroying)return;const i="reconnecting"===this.agentState?this.stateBeforeReconnect:this.agentState;this.cancelReconnect();let s=()=>{},r=e=>{};const a=new Promise((e,t)=>{s=e,r=t});a.catch(()=>{});const o={reconnect:e,previousState:i,phase:"draining",departAt:Date.now()+Math.max(0,t-3e3),quietUntil:0,audioStopped:!1,timer:null,expiryTimer:null,completion:a,resolve:s,reject:r};if(this.serviceMigration=o,this.stateBeforeReconnect=this.readRestorableState(),!e)return void this.failServiceMigration("E2E_SERVICE_UPDATE_INVALID","服务更新缺少有效的同房重连凭据");if(o.expiryTimer=setTimeout(()=>{this.failServiceMigration("E2E_MIGRATION_TOKEN_EXPIRED","E2E 迁移凭据已过期,请结束会话后重新初始化")},Math.max(0,e.expiresAt-Date.now())),this.setMigrationState("reconnecting"),this.serviceMigration!==o||this.agentDestroying)return;const l=Boolean((null==(n=this.microphone)?void 0:n.isRecording)||this.stopASRPromise||this.audioInputEnabled);o.timer=setTimeout(()=>{this.closeForServiceMigration(o)},Math.max(0,o.departAt-Date.now())),this.stopASR().then(()=>{this.serviceMigration===o&&"draining"===o.phase&&(o.audioStopped=!0,o.quietUntil=Date.now()+(l?2e3:0),this.checkServiceMigration())}).catch(()=>{this.serviceMigration===o&&this.failServiceMigration("E2E_MIGRATION_AUDIO_STOP_FAILED","E2E 迁移时停止音频失败")})}checkServiceMigration(){const e=this.serviceMigration;if(!e||"draining"!==e.phase||!e.audioStopped)return;const t=e.quietUntil-Date.now();Date.now()>=e.departAt||t<=0&&!this.interactionPending&&!this.llmPending&&!this.directSpeakOpen&&!this.pendingASR&&!this.voicePlaying?this.closeForServiceMigration(e):t>0?(null!==e.timer&&clearTimeout(e.timer),e.timer=setTimeout(()=>this.checkServiceMigration(),Math.max(0,Math.min(t,e.departAt-Date.now())))):(null!==e.timer&&clearTimeout(e.timer),e.timer=setTimeout(()=>{this.closeForServiceMigration(e)},Math.max(0,e.departAt-Date.now())))}async closeForServiceMigration(e){var t;if(this.serviceMigration!==e||"draining"!==e.phase||this.agentDestroying||this.agentDestroyed)return;e.phase="closing",null!==e.timer&&clearTimeout(e.timer),e.timer=null,this.audioUplink.reset(),this.audioInputEnabled=!1;const n=this.e2eClient,i=await(null==n?void 0:n.disconnectAndWait(1e3,"service_update",3e3));if(this.serviceMigration===e&&"closing"===e.phase&&!this.agentDestroying&&!this.agentDestroyed)if(!1!==i){this.e2eClient===n&&(this.e2eClient=null);try{await this.replaceE2EConnection(e.reconnect,!1)}catch(t){return void(this.serviceMigration===e&&this.failServiceMigration("E2E_MIGRATION_FAILED","创建迁移连接失败"))}this.serviceMigration!==e||this.agentDestroying||this.agentDestroyed||(e.phase="connecting",this.interactionPending=!1,this.llmPending=!1,this.llmProducedText=!1,this.directSpeakOpen=!1,this.pendingASR=!1,this.voicePlaying=!1,this.scheduleServiceReconnect(e,0===(null==(t=e.reconnect)?void 0:t.attempts)))}else this.failServiceMigration("E2E_MIGRATION_CLOSE_TIMEOUT","旧 E2E 未确认关闭,已停止迁移以避免双连接")}scheduleServiceReconnect(e,t=!1){var n,i;if(this.serviceMigration!==e||"connecting"!==e.phase||this.agentDestroying||this.agentDestroyed||this.reconnectInFlight)return;null!==e.timer&&clearTimeout(e.timer);const s=t?0:Math.max(100,this.getReconnectDelay((null!=(n=null==(i=e.reconnect)?void 0:i.attempts)?n:1)-1));e.timer=setTimeout(()=>{this.attemptServiceReconnect(e)},s)}async attemptServiceReconnect(e){if(this.serviceMigration!==e||"connecting"!==e.phase||this.agentDestroying||this.agentDestroyed)return;e.timer=null;const t=this.e2eClient;if(!t||!e.reconnect)return;if(Date.now()>=e.reconnect.expiresAt)return void this.failServiceMigration("E2E_MIGRATION_TOKEN_EXPIRED","E2E 迁移凭据已过期,请结束会话后重新初始化");this.reconnectInFlight=!0,e.reconnect.attempts+=1;const n=setTimeout(()=>t.disconnect(1e3,"migration_connect_timeout"),1e4);try{if(await t.connect(),clearTimeout(n),this.serviceMigration!==e||!t.isOpen||this.agentDestroying||this.agentDestroyed)return;if(await this.stopASRPromise,this.serviceMigration!==e||!t.isOpen||this.agentDestroying||this.agentDestroyed)return;try{this.setASRState("idle")}catch(e){}if(this.serviceMigration===e&&!this.agentDestroyed&&!this.agentDestroying){const t=e.previousState;this.cancelServiceMigration(),this.setMigrationState(t)}}catch(e){}finally{clearTimeout(n),this.serviceMigration===e&&(this.reconnectInFlight=!1,this.scheduleServiceReconnect(e))}}failServiceMigration(e,t){var n;const i=this.serviceMigration;i&&"failed"!==i.phase&&(i.phase="failed",null!==i.timer&&clearTimeout(i.timer),null!==i.expiryTimer&&clearTimeout(i.expiryTimer),i.timer=null,i.expiryTimer=null,this.cancelReconnect(),this.stopASRAfterSocketClose(),null==(n=this.e2eClient)||n.disconnect(1e3,"migration_failed"),i.reject(new Error(t)),this.abortInitialization(new Error(t)),this.setMigrationState("failed"),this.emitError("E2E_CLOSE_4009"===e?"quota":"network",e,t,!1))}setMigrationState(e){try{this.setAgentState(e)}catch(e){}}cancelServiceMigration(){const e=this.serviceMigration;e&&(this.serviceMigration=null,null!==e.timer&&clearTimeout(e.timer),null!==e.expiryTimer&&clearTimeout(e.expiryTimer),this.reconnectInFlight=!1,e.resolve())}handleSocketClose(e){if(this.agentDestroyed||this.agentDestroying)return;if(this.serviceMigration){const t=this.serviceMigration;return void("draining"===t.phase?4011===e.code||x.has(e.code)?this.closeForServiceMigration(t):this.failServiceMigration(`E2E_CLOSE_${e.code}`,"E2E 更新迁移被服务端终止"):"connecting"===t.phase&&(4011===e.code||x.has(e.code)?this.scheduleServiceReconnect(t):this.failServiceMigration(`E2E_CLOSE_${e.code}`,"E2E 更新迁移被服务端终止")))}if(4011===e.code)return void this.startServiceMigration(this.serviceReconnect,0);if(this.rejectInitialization)return void this.abortInitialization(new Error(`Agent 初始化期间 E2E WebSocket 已关闭: ${e.code} ${e.reason||""}`.trim()));if(this.audioUplink.reset(),this.stopASRAfterSocketClose(),this.shouldReconnect(e))return void this.beginReconnect(e);this.setAgentState("failed");const t=4009===e.code?"quota":"network";this.emitError(t,`E2E_CLOSE_${e.code}`,e.reason||B[e.code]||"E2E WebSocket 已关闭","quota"!==t,{code:e.code,reason:e.reason,wasClean:e.wasClean})}shouldReconnect(e){return this.reconnectOptions.enabled&&"idle"!==this.agentState&&"initializing"!==this.agentState&&"destroyed"!==this.agentState&&x.has(e.code)}beginReconnect(e){var t;"reconnecting"!==this.agentState&&(this.stateBeforeReconnect=this.readRestorableState(),this.reconnectAttempt=0,this.sessionReloadFallback=!1,this.setAgentState("reconnecting"),null==globalThis.addEventListener||globalThis.addEventListener("online",this.handleOnlineForReconnect),this.emitError("network","E2E_RECONNECTING","E2E WebSocket 已断开,正在重连",!0,{code:e.code,reason:e.reason,wasClean:e.wasClean})),this.audioInputEnabled=!1,null==(t=this.e2eClient)||t.setAudioInputEnabled(!1),this.scheduleE2EReconnect(!1)}scheduleE2EReconnect(e){if(this.agentDestroyed||this.agentDestroying||this.serviceMigration||"reconnecting"!==this.agentState||null!==this.reconnectTimer||this.reconnectInFlight||this.sessionReloadFallback)return;if(this.reconnectAttempt>=this.reconnectOptions.maxAttempts)return void this.fallbackToSessionReload();const t=e?0:this.getReconnectDelay(this.reconnectAttempt);this.reconnectTimer=globalThis.setTimeout(()=>{this.reconnectTimer=null,this.attemptE2EReconnect()},t)}async attemptE2EReconnect(){const e=this.e2eClient;if(e&&!this.serviceMigration&&!this.agentDestroyed&&!this.agentDestroying&&"reconnecting"===this.agentState){this.reconnectInFlight=!0,this.reconnectAttempt+=1;try{await e.connect(),this.e2eClient!==e||this.serviceMigration||this.agentDestroyed||this.agentDestroying||this.waitingForTtsaReload||this.finishReconnect()}catch(t){this.e2eClient!==e||this.serviceMigration||this.agentDestroyed||this.agentDestroying||this.scheduleE2EReconnect(!1)}finally{this.e2eClient!==e||this.serviceMigration||(this.reconnectInFlight=!1),this.e2eClient!==e||this.serviceMigration||"reconnecting"!==this.agentState||null!==this.reconnectTimer||this.sessionReloadFallback||this.scheduleE2EReconnect(!1)}}}async fallbackToSessionReload(){if(!(this.serviceMigration||this.sessionReloadFallback||this.agentDestroyed||this.agentDestroying)){this.sessionReloadFallback=!0,this.clearReconnectTimer();try{await this.restartSessionForTransport("e2e_reconnect_exhausted")}catch(e){this.failReconnect(e)}}}finishReconnect(){const e=this.stateBeforeReconnect;this.cancelReconnect(),"idle"!==this.asrState&&this.setASRState("idle"),this.setAgentState(e)}failReconnect(e){this.cancelReconnect(),this.setAgentState("failed"),this.emitConversation({state:"failed"}),this.emitError("network","E2E_RECONNECT_EXHAUSTED","E2E WebSocket 重连失败,请重新初始化 Agent",!1,e)}cancelReconnect(){this.clearReconnectTimer(),null==globalThis.removeEventListener||globalThis.removeEventListener("online",this.handleOnlineForReconnect),this.reconnectAttempt=0,this.reconnectInFlight=!1,this.sessionReloadFallback=!1,this.waitingForTtsaReload=!1}clearReconnectTimer(){null!==this.reconnectTimer&&(globalThis.clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}getReconnectDelay(e){if(0===this.reconnectOptions.initialDelayMs)return 0;const t=Math.min(this.reconnectOptions.maxDelayMs,this.reconnectOptions.initialDelayMs*2**e);return 0===t?0:Math.round(t*(.8+.4*Math.random()))}readRestorableState(){return"running"===this.agentState||"stopped"===this.agentState||"ready"===this.agentState?this.agentState:"ready"}normalizeReconnectOptions(e){var t;const n=this.readNonNegativeNumber(null==e?void 0:e.initialDelayMs,500);return{enabled:null==(t=null==e?void 0:e.enabled)||t,maxAttempts:Math.max(1,Math.floor(this.readNonNegativeNumber(null==e?void 0:e.maxAttempts,6))),initialDelayMs:n,maxDelayMs:Math.max(n,this.readNonNegativeNumber(null==e?void 0:e.maxDelayMs,8e3))}}readNonNegativeNumber(e,t){return"number"==typeof e&&Number.isFinite(e)&&e>=0?e:t}stopASRAfterSocketClose(){if(this.asrStartGeneration+=1,this.stopASRPromise)return;const e=this.microphone;null!=e&&e.isRecording&&(this.microphone=null,this.stopASRPromise=this.finishStopASR(e,!1).catch(e=>{this.emitError("sdk","MICROPHONE_CLEANUP_FAILED","WebSocket 断开后清理麦克风失败",!1,e)}).finally(()=>{this.stopASRPromise=null}))}setAgentState(e){var t;this.agentState=e,this.agentDestroyed&&"destroyed"!==e||null==(t=this.agentOptions.callbacks)||null==t.onAgentStateChange||t.onAgentStateChange(e)}setASRState(e){this.asrState=e,this.safeEmit(()=>{var t;return null==(t=this.agentOptions.callbacks)||null==t.onASRStateChange?void 0:t.onASRStateChange(e)})}emitConversation(e){this.safeEmit(()=>{var t;return null==(t=this.agentOptions.callbacks)||null==t.onConversationChange?void 0:t.onConversationChange(e)})}emitError(e,t,n,i,s){const r={domain:e,code:t,message:n,retryable:i,cause:s};"asr"===e&&this.setASRState("failed"),this.safeEmit(()=>{var e;return null==(e=this.agentOptions.callbacks)||null==e.onError?void 0:e.onError(r)})}safeEmit(e){this.agentDestroyed||this.agentDestroying||e()}assertRunning(){if(this.assertE2EOpen(),this.serviceMigration)throw new Error("Agent 正在迁移 E2E,请等待恢复后再开始新交互");if("running"!==this.agentState)throw new Error("Agent 尚未启动,请先调用 start()")}assertASRStartAllowed(){if(this.assertRunning(),this.getStatus()===i.invisible)throw new Error("数字人处于隐身状态,无法启动 ASR,请先退出隐身模式")}assertE2EOpen(){var e;if(this.assertNotDestroyed(),null==(e=this.e2eClient)||!e.isOpen)throw new Error("Agent 尚未连接 E2E WebSocket")}assertNotDestroyed(){if(this.agentDestroyed||this.agentDestroying)throw new Error("Agent 已销毁")}}export{G as default};
@@ -1 +0,0 @@
1
- import e from"@xmov/avatar";function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,a(r.key),r)}}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function i(e,n){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(r)return(r=r.call(e)).next.bind(r);if(Array.isArray(e)||(r=function(e,n){if(e){if("string"==typeof e)return t(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(e,n):void 0}}(e))||n&&e&&"number"==typeof e.length){r&&(e=r);var i=0;return function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o.apply(null,arguments)}function s(e,t){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},s(e,t)}function a(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var u,c,l,h;!function(e){e[e.CONTAINER_NOT_FOUND=10001]="CONTAINER_NOT_FOUND",e[e.CONNECT_SOCKET_ERROR=10002]="CONNECT_SOCKET_ERROR",e[e.START_SESSION_ERROR=10003]="START_SESSION_ERROR",e[e.STOP_SESSION_ERROR=10004]="STOP_SESSION_ERROR",e[e.INIT_ERROR=10005]="INIT_ERROR",e[e.SOCKET_QUIT=10006]="SOCKET_QUIT",e[e.SOCKET_DISCONNECT=10007]="SOCKET_DISCONNECT",e[e.VIDEO_FRAME_EXTRACT_ERROR=20001]="VIDEO_FRAME_EXTRACT_ERROR",e[e.INIT_WORKER_ERROR=20002]="INIT_WORKER_ERROR",e[e.PROCESS_VIDEO_STREAM_ERROR=20003]="PROCESS_VIDEO_STREAM_ERROR",e[e.FACE_PROCESSING_ERROR=20004]="FACE_PROCESSING_ERROR",e[e.RENDER_BODY_ERROR=20005]="RENDER_BODY_ERROR",e[e.RENDER_FACE_ERROR=20006]="RENDER_FACE_ERROR",e[e.WebGL_RENDER_ERROR=20007]="WebGL_RENDER_ERROR",e[e.RENDER_DATA_MISSING=20008]="RENDER_DATA_MISSING",e[e.RENDER_FACE_DATA_MISSING=20009]="RENDER_FACE_DATA_MISSING",e[e.EVENT_WITHOUT_SPEECH_ID=20010]="EVENT_WITHOUT_SPEECH_ID",e[e.EVENT_TRIGGERED=20011]="EVENT_TRIGGERED",e[e.BACKGROUND_IMAGE_LOAD_ERROR=30001]="BACKGROUND_IMAGE_LOAD_ERROR",e[e.FACE_BIN_LOAD_ERROR=30002]="FACE_BIN_LOAD_ERROR",e[e.INVALID_BODY_NAME=30003]="INVALID_BODY_NAME",e[e.VIDEO_DOWNLOAD_ERROR=30004]="VIDEO_DOWNLOAD_ERROR",e[e.BODY_DATA_EXPIRED=30005]="BODY_DATA_EXPIRED",e[e.EVENT_SPEAK_START_EXPIRED=30006]="EVENT_SPEAK_START_EXPIRED",e[e.EVENT_VOICE_START_EXPIRED=30007]="EVENT_VOICE_START_EXPIRED",e[e.AUDIO_DECODE_ERROR=40001]="AUDIO_DECODE_ERROR",e[e.FACE_DECODE_ERROR=40002]="FACE_DECODE_ERROR",e[e.VIDEO_DECODE_ERROR=40003]="VIDEO_DECODE_ERROR",e[e.EVENT_DECODE_ERROR=40004]="EVENT_DECODE_ERROR",e[e.INVALID_DATA_STRUCTURE=40005]="INVALID_DATA_STRUCTURE",e[e.TTSA_ERROR=40006]="TTSA_ERROR",e[e.AUDIO_DATA_EXPIRED=40007]="AUDIO_DATA_EXPIRED",e[e.NETWORK_DOWN=50001]="NETWORK_DOWN",e[e.NETWORK_UP=50002]="NETWORK_UP",e[e.NETWORK_RETRY=50003]="NETWORK_RETRY",e[e.NETWORK_BREAK=50004]="NETWORK_BREAK",e[e.WEBGL_CONTEXT_LOST=60001]="WEBGL_CONTEXT_LOST",e[e.WEBGL_CONTEXT_RESTORED=60002]="WEBGL_CONTEXT_RESTORED",e[e.WEBGL_CONTEXT_RESTORE_TIMEOUT=60003]="WEBGL_CONTEXT_RESTORE_TIMEOUT",e[e.WEBGL_CONTEXT_RECOVERED=60004]="WEBGL_CONTEXT_RECOVERED",e[e.WEBGL_CONTEXT_RECOVERY_FAILED=60005]="WEBGL_CONTEXT_RECOVERY_FAILED",e[e.WEBGL_CONTEXT_RECOVERY_MAX_ATTEMPTS=60006]="WEBGL_CONTEXT_RECOVERY_MAX_ATTEMPTS",e[e.WEBGL_RESOLUTION_RESTORED=60007]="WEBGL_RESOLUTION_RESTORED",e[e.WEBGL_CONTEXT_MANUAL_RESTARTED=60008]="WEBGL_CONTEXT_MANUAL_RESTARTED"}(u||(u={})),function(e){e[e.online=0]="online",e[e.offline=1]="offline",e[e.network_on=2]="network_on",e[e.network_off=3]="network_off",e[e.close=4]="close",e[e.visible=5]="visible",e[e.invisible=6]="invisible",e[e.stopped=7]="stopped"}(c||(c={})),function(e){e.init="init",e.rendering="rendering",e.pausing="pausing",e.paused="paused",e.resumed="resumed",e.stopped="stopped"}(l||(l={})),function(e){e.normal="normal",e.invisible="invisible"}(h||(h={}));var d=2097152,f=/*#__PURE__*/function(){function e(e){var t;this.ws=null,this.connectPromise=null,this.rejectConnect=null,this.options=e,this.audioInputEnabled=null==(t=e.audioInputEnabled)||t;var n=e.WebSocketCtor||globalThis.WebSocket;if(!n)throw new Error("当前环境不支持 WebSocket");this.WebSocketCtor=n}var t=e.prototype;return t.connect=function(){var e,t,n,r=this;return this.isOpen?Promise.resolve():(this.connectPromise||(null==(e=(t=this.options).onStateChange)||e.call(t,"connecting"),n=new Promise(function(e,t){r.rejectConnect=t;var i=!1,o=new r.WebSocketCtor(r.buildWsUrl(r.options.wsUrl,r.options.token));r.ws=o,o.onopen=function(){r.ws===o&&(i=!0,r.connectPromise===n&&(r.connectPromise=null),r.rejectConnect=null,null==r.options.onStateChange||r.options.onStateChange("open"),e())},o.onmessage=function(e){if(r.ws===o){var t=r.parseMessage(e.data);t&&(null==r.options.onEvent||r.options.onEvent(t))}},o.onerror=function(){if(r.ws===o){var e=new Error("E2E WebSocket 连接异常");i||(i=!0,r.connectPromise===n&&(r.connectPromise=null),r.rejectConnect=null,t(e)),null==r.options.onStateChange||r.options.onStateChange("error"),null==r.options.onError||r.options.onError(e)}},o.onclose=function(e){r.ws===o&&(r.ws=null,i||(i=!0,r.connectPromise===n&&(r.connectPromise=null),r.rejectConnect=null,t(new Error(("E2E WebSocket 已关闭: "+e.code+" "+(e.reason||"")).trim()))),null==r.options.onStateChange||r.options.onStateChange("closed"),null==r.options.onClose||r.options.onClose(e))}}),this.connectPromise=n),this.connectPromise)},t.disconnect=function(e,t){void 0===e&&(e=1e3),void 0===t&&(t="client_close");var n=this.detachSocket();n&&this.closeSocket(n,e,t)},t.disconnectAndWait=function(e,t,n){var r=this;void 0===e&&(e=1e3),void 0===t&&(t="client_close"),void 0===n&&(n=3e3);var i=this.ws;return i?(this.cancelPendingConnection(),new Promise(function(o){var s,a=i.onclose,u=!1,c=function(e){u||(u=!0,void 0!==s&&globalThis.clearTimeout(s),r.ws===i&&(r.ws=null),i.onclose=a,o(e))};i.onclose=function(e){try{null==a||a.call(i,e)}finally{c(!0)}},s=globalThis.setTimeout(function(){return c(!1)},Math.max(0,n));try{r.closeSocket(i,e,t)}catch(e){c(!1)}})):Promise.resolve(!0)},t.detachSocket=function(){if(!this.ws)return null;var e=this.ws;return this.ws=null,this.cancelPendingConnection(),e},t.cancelPendingConnection=function(){this.connectPromise=null;var e=this.rejectConnect;this.rejectConnect=null,null==e||e(new Error("E2E WebSocket 连接已取消"))},t.closeSocket=function(e,t,n){e.readyState!==this.WebSocketCtor.OPEN&&e.readyState!==this.WebSocketCtor.CONNECTING||e.close(t,n)},t.send=function(e){var t;this.assertOpen(),null==(t=this.ws)||t.send(JSON.stringify(e))},t.trySend=function(e){var t;return this.assertOpen(),!(this.ws&&this.ws.bufferedAmount>d||(null==(t=this.ws)||t.send(JSON.stringify(e)),0))},t.sendBinary=function(e){var t;if(this.assertOpen(),this.ws&&this.ws.bufferedAmount>d){var n=new Error("E2E WebSocket 发送缓冲区超限");throw n.name="WebSocketBackpressureError",n}null==(t=this.ws)||t.send(e)},t.ping=function(){this.send({type:"ping"})},t.setAudioInputEnabled=function(e){this.audioInputEnabled=e},t.assertOpen=function(){if(!this.isOpen)throw new Error("E2E WebSocket 未连接")},t.parseMessage=function(e){if("string"!=typeof e)return null;try{var t=JSON.parse(e);return t&&"string"==typeof t.type?t:null}catch(e){var n,r;return null==(n=(r=this.options).onError)||n.call(r,new Error("E2E WebSocket 消息不是合法 JSON")),null}},t.buildWsUrl=function(e,t){try{var n=new URL(e);return!t||n.searchParams.has("token")||n.searchParams.has("e2e_token")||n.searchParams.set("token",t),this.updateAudioInputQuery(n.searchParams),n.toString()}catch(n){var r=e.split("?",2),i=r[0],o=r[1],s=new URLSearchParams(void 0===o?"":o);!t||s.has("token")||s.has("e2e_token")||s.set("token",t),this.updateAudioInputQuery(s);var a=s.toString();return a?i+"?"+a:i}},t.updateAudioInputQuery=function(e){this.audioInputEnabled?e.delete("audio_input_off"):e.set("audio_input_off","1")},r(e,[{key:"isOpen",get:function(){var e;return(null==(e=this.ws)?void 0:e.readyState)===this.WebSocketCtor.OPEN}}])}(),m={format:"webm_opus",mimeType:"audio/webm;codecs=opus",sampleRate:16e3,channels:1,chunkMs:100};function p(e,t){try{var n=e()}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}var v=16e3,g="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function E(e,t,n){if(!e.s){if(n instanceof S){if(!n.s)return void(n.o=E.bind(null,e,t));1&t&&(t=n.s),n=n.v}if(n&&n.then)return void n.then(E.bind(null,e,t),E.bind(null,e,2));e.s=t,e.v=n;var r=e.o;r&&r(e)}}var S=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(t,n){var r=new e,i=this.s;if(i){var o=1&i?t:n;if(o){try{E(r,1,o(this.v))}catch(e){E(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?E(r,1,t?t(i):i):n?E(r,1,n(i)):E(r,2,i)}catch(e){E(r,2,e)}},r},e}();function y(e){return e instanceof S&&1&e.s}function R(e,t,n){if("function"==typeof e[g]){var r,i,o,s=function(e){try{for(;!((r=a.next()).done||n&&n());)if((e=t(r.value))&&e.then){if(!y(e))return void e.then(s,o||(o=E.bind(null,i=new S,2)));e=e.v}i?E(i,1,e):i=e}catch(e){E(i||(i=new S),2,e)}},a=e[g]();if(s(),a.return){var u=function(e){try{r.done||a.return()}catch(e){}return e};if(i&&i.then)return i.then(u,function(e){throw u(e)});u()}return i}if(!("length"in e))throw new TypeError("Object is not iterable");for(var c=[],l=0;l<e.length;l++)c.push(e[l]);return function(e,t,n){var r,i,o=-1;return function s(a){try{for(;++o<e.length&&(!n||!n());)if((a=t(o))&&a.then){if(!y(a))return void a.then(s,i||(i=E.bind(null,r=new S,2)));a=a.v}r?E(r,1,a):r=a}catch(e){E(r||(r=new S),2,e)}}(),r}(c,function(e){return t(c[e])},n)}function A(e,t){try{var n=e()}catch(e){return t(!0,e)}return n&&n.then?n.then(t.bind(null,!1),t.bind(null,!0)):t(!1,n)}var b=/*#__PURE__*/function(){function e(e){void 0===e&&(e={}),this.inputTrack=null,this.reader=null,this.writer=null,this.generator=null,this.audioContext=null,this.audioSource=null,this.audioDestination=null,this.pumpPromise=null,this.pumpFinished=!1,this.outputClosed=!1,this.draining=!1,this.inputSampleRate=null,this.resampleBuffer=[],this.resamplePosition=0,this.outputBuffer=[],this.outputTimestamp=null,this.startGeneration=0,this.options=e}var t=e.prototype;return t.start=function(e){try{var t=this,n=++t.startGeneration;t.inputTrack=e,t.inputSampleRate=null,t.resampleBuffer=[],t.resamplePosition=0,t.outputBuffer=[],t.outputTimestamp=null,t.pumpFinished=!1,t.outputClosed=!1,t.draining=!1;var r=globalThis,i=r.MediaStreamTrackProcessor,o=r.MediaStreamTrackGenerator,s=r.AudioData;if(!i||!o||!s)return Promise.resolve(t.startWebAudio(e,r,n));var a=new i({track:e}),u=new o({kind:"audio"}),c=new MediaStream([u]),l=c.getAudioTracks()[0],h=null==l?void 0:l.getSettings();if(void 0!==(null==h?void 0:h.sampleRate)&&h.sampleRate!==v||void 0!==(null==h?void 0:h.channelCount)&&1!==h.channelCount)throw u.stop(),t.unsupported("浏览器音频输出格式不符合要求: "+((null==h?void 0:h.sampleRate)||"unknown")+" Hz / "+((null==h?void 0:h.channelCount)||"unknown")+" channel");try{t.reader=a.readable.getReader(),t.writer=u.writable.getWriter()}catch(n){throw u.stop(),"ended"!==e.readyState&&e.stop(),t.inputTrack=null,n}return t.generator=u,t.pumpPromise=t.pump(s),Promise.resolve(c)}catch(e){return Promise.reject(e)}},t.startWebAudio=function(e,t,n){try{var r=this,i=globalThis.AudioContext||t.webkitAudioContext;if(!i)throw r.unsupported("当前浏览器不支持 16 kHz mono 音频处理");var o=null,s=null,a=null;return Promise.resolve(p(function(){function t(t){if(r.assertStartActive(n),"running"!==o.state)throw r.contextSuspended();s=o.createMediaStreamSource(new MediaStream([e])),r.audioSource=s,a=o.createMediaStreamDestination(),r.audioDestination=a,a.channelCount=1,a.channelCountMode="explicit",a.channelInterpretation="speakers",s.connect(a);var i=a.stream.getAudioTracks()[0];if(!i)throw new Error("Web Audio 未返回音频输出轨道");return r.validateOutputTrack(i),r.assertStartActive(n),a.stream}if(o=new i({sampleRate:v}),r.audioContext=o,o.sampleRate!==v)throw r.unsupported("浏览器无法创建 16 kHz AudioContext: "+o.sampleRate+" Hz");var u=function(){if("suspended"===o.state)return p(function(){return Promise.resolve(o.resume()).then(function(){})},function(e){throw r.contextSuspended(e)})}();return u&&u.then?u.then(t):t()},function(t){var n,i;function u(){throw"ended"!==e.readyState&&e.stop(),r.inputTrack=null,r.audioContext===o&&(r.audioContext=null,r.audioSource=null,r.audioDestination=null),r.normalizeWebAudioError(t)}null==(n=s)||n.disconnect(),null==(i=a)||i.stream.getTracks().forEach(function(e){return e.stop()});var c=function(){if(o&&"closed"!==o.state)return Promise.resolve(o.close().catch(function(){})).then(function(){})}();return c&&c.then?c.then(u):u()}))}catch(e){return Promise.reject(e)}},t.stop=function(){try{var e=this;return Promise.resolve(e.drain()).then(function(){var t;function n(n){return t?n:Promise.resolve(e.closeOutput()).then(function(){})}var r=function(){if(e.audioContext)return Promise.resolve(e.closeWebAudioOutput()).then(function(){t=1})}();return r&&r.then?r.then(n):n(r)})}catch(e){return Promise.reject(e)}},t.drain=function(){try{var e,t=this;if(t.startGeneration+=1,t.draining=!0,null==(e=t.inputTrack)||e.stop(),t.inputTrack=null,t.audioContext)return Promise.resolve();var n=t.pumpPromise,r=function(){if(n){var e=n.then(function(){return!0},function(){return!0});return Promise.resolve(Promise.race([e,t.delay(1e3)])).then(function(e){var n=function(){var n;if(!e)return Promise.resolve(Promise.race([null==(n=t.reader)?void 0:n.cancel().catch(function(){}),t.delay(100)])).then(function(){var e;return Promise.resolve(Promise.race([null==(e=t.writer)?void 0:e.abort(new Error("16 kHz mono 音频处理停止超时")).catch(function(){}),t.delay(100)])).then(function(){t.stopGenerator()})})}();if(n&&n.then)return n.then(function(){})})}}();return Promise.resolve(r&&r.then?r.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},t.closeOutput=function(){try{var e=function(){t.stopGenerator(),n&&t.pumpFinished&&n.releaseLock(),t.reader=null,t.writer=null,t.generator=null,t.pumpPromise=null},t=this,n=t.writer;t.outputClosed=!0;var r=n&&t.pumpFinished?Promise.resolve(Promise.race([n.close().catch(function(){}),t.delay(100)])).then(function(){}):Promise.resolve(Promise.race([null==n?void 0:n.abort(new Error("16 kHz mono 音频处理停止超时")).catch(function(){}),t.delay(100)])).then(function(){});return Promise.resolve(r&&r.then?r.then(e):e())}catch(e){return Promise.reject(e)}},t.closeWebAudioOutput=function(){try{var e=this,t=e.audioContext,n=e.audioSource,r=e.audioDestination;e.audioContext=null,e.audioSource=null,e.audioDestination=null,null==n||n.disconnect(),null==r||r.disconnect(),null==r||r.stream.getTracks().forEach(function(e){return e.stop()});var i=function(){if(t&&"closed"!==t.state)return Promise.resolve(t.close().catch(function(){})).then(function(){})}();return Promise.resolve(i&&i.then?i.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},t.pump=function(e){try{var t=this,n=t.reader,r=t.writer;return n&&r?Promise.resolve(A(function(){return p(function(){var i;function o(){function n(){var e;if(s&&!t.draining&&"ended"===(null==(e=t.inputTrack)?void 0:e.readyState)){var n=new Error("麦克风音频轨道已结束");n.name="AudioTransformError",null==t.options.onError||t.options.onError(n),t.stopGenerator()}}var i=R(t.resample(new Float32Array,t.inputSampleRate||v,!0),function(n){return Promise.resolve(t.writeChunk(r,e,n)).then(function(){})});return i&&i.then?i.then(n):n()}var s=!1,a=function(e,t,n){for(var r;;){var i=e();if(y(i)&&(i=i.v),!i)return o;if(i.then){r=0;break}var o=n();if(o&&o.then){if(!y(o)){r=1;break}o=o.s}}var s=new S,a=E.bind(null,s,2);return(0===r?i.then(c):1===r?o.then(u):(void 0).then(function(){(i=e())?i.then?i.then(c).then(void 0,a):c(i):E(s,1,o)})).then(void 0,a),s;function u(t){o=t;do{if(!(i=e())||y(i)&&!i.v)return void E(s,1,o);if(i.then)return void i.then(c).then(void 0,a);y(o=n())&&(o=o.v)}while(!o||!o.then);o.then(u).then(void 0,a)}function c(e){e?(o=n())&&o.then?o.then(u).then(void 0,a):u(o):E(s,1,o)}}(function(){return!i},0,function(){return Promise.resolve(n.read()).then(function(n){if(n.done)return s=!0,void(i=1);if(n.value){var o=n.value;return A(function(){t.validateAudioData(o);var n=t.toMono(o),i=t.resample(n,o.sampleRate,!1);null===t.outputTimestamp&&(t.outputTimestamp=Number.isFinite(o.timestamp)?o.timestamp:0);var s=R(i,function(n){return Promise.resolve(t.writeChunk(r,e,n)).then(function(){})});if(s&&s.then)return s.then(function(){})},function(e,t){if(o.close(),e)throw t;return t})}})});return a&&a.then?a.then(o):o()},function(e){var n=e instanceof Error?e:new Error("16 kHz mono 音频处理失败");n.name="AudioTransformError",null==t.options.onError||t.options.onError(n)})},function(e,i){if(n.releaseLock(),t.pumpFinished=!0,t.outputClosed&&r.releaseLock(),e)throw i;return i})):Promise.resolve()}catch(e){return Promise.reject(e)}},t.toMono=function(e){for(var t=Math.max(1,e.numberOfChannels),n=new Float32Array(e.numberOfFrames),r=0;r<t;r+=1){var i=new Float32Array(e.numberOfFrames);e.copyTo(i,{format:"f32-planar",planeIndex:r});for(var o=0;o<i.length;o+=1)n[o]+=i[o]/t}return n},t.resample=function(e,t,n){if(null===this.inputSampleRate)this.inputSampleRate=t;else if(this.inputSampleRate!==t)throw new Error("输入音频采样率发生变化: "+this.inputSampleRate+" -> "+t);for(var r,o=i(e);!(r=o()).done;)this.resampleBuffer.push(r.value);if(this.resampleBuffer.length>192e3)throw new Error("输入音频重采样缓冲区超限");n&&this.resampleBuffer.length>0&&this.resampleBuffer.push(this.resampleBuffer[this.resampleBuffer.length-1]);for(var s=t/v,a=[];this.resamplePosition+1<this.resampleBuffer.length;){var u=Math.floor(this.resamplePosition),c=Math.min(u+1,this.resampleBuffer.length-1),l=this.resamplePosition-u;this.outputBuffer.push(this.resampleBuffer[u]*(1-l)+this.resampleBuffer[c]*l),this.resamplePosition+=s;var h=Math.floor(this.resamplePosition);h>0&&(this.resampleBuffer.splice(0,h),this.resamplePosition-=h),this.outputBuffer.length>=320&&a.push(new Float32Array(this.outputBuffer.splice(0,320)))}return n&&this.outputBuffer.length>0&&a.push(new Float32Array(this.outputBuffer.splice(0))),a},t.writeChunk=function(e,t,n){try{var r=this;if(!n.length)return Promise.resolve();var i=r.outputTimestamp||0,o=new t({format:"f32-planar",sampleRate:v,numberOfFrames:n.length,numberOfChannels:1,timestamp:i,data:n});return r.outputTimestamp=i+Math.round(1e6*n.length/v),Promise.resolve(e.write(o)).then(function(){var e;o.close();var t=null==(e=r.generator)?void 0:e.getSettings();if(t&&(void 0!==t.sampleRate&&t.sampleRate!==v||void 0!==t.channelCount&&1!==t.channelCount))throw r.unsupported("浏览器音频输出格式不符合要求: "+(t.sampleRate||"unknown")+" Hz / "+(t.channelCount||"unknown")+" channel")})}catch(e){return Promise.reject(e)}},t.validateAudioData=function(e){if(!Number.isFinite(e.sampleRate)||!Number.isInteger(e.sampleRate)||e.sampleRate<8e3||e.sampleRate>192e3)throw new Error("输入音频采样率无效: "+e.sampleRate);if(!Number.isInteger(e.numberOfChannels)||e.numberOfChannels<1||e.numberOfChannels>8)throw new Error("输入音频声道数无效: "+e.numberOfChannels);if(!Number.isInteger(e.numberOfFrames)||e.numberOfFrames<1||e.numberOfFrames>96e3)throw new Error("输入音频帧数无效: "+e.numberOfFrames);if(!Number.isFinite(e.timestamp)||Math.abs(e.timestamp)>1e15)throw new Error("输入音频时间戳无效: "+e.timestamp)},t.delay=function(e){return new Promise(function(t){globalThis.setTimeout(function(){return t(!1)},e)})},t.stopGenerator=function(){this.generator&&"ended"!==this.generator.readyState&&this.generator.stop()},t.unsupported=function(e,t){var n=new Error(e);return n.name="NotSupportedError",n.agentCode="AUDIO_FIXED_TRACK_UNSUPPORTED",n.retryable=!1,n.cause=t,n},t.contextSuspended=function(e){var t=new Error("AudioContext 未运行,请在用户操作后重试");return t.name="NotAllowedError",t.agentCode="AUDIO_CONTEXT_SUSPENDED",t.retryable=!0,t.cause=e,t},t.assertStartActive=function(e){if(e!==this.startGeneration){var t=new Error("16 kHz mono 音频处理启动已取消");throw t.name="AbortError",t.agentCode="AUDIO_FIXED_TRACK_CANCELLED",t.retryable=!0,t}},t.normalizeWebAudioError=function(e){var t=e instanceof Error?e:new Error(String(e));if(t.agentCode)return t;if("NotSupportedError"===t.name)return this.unsupported("浏览器无法初始化 16 kHz mono Web Audio: "+t.message,t);var n=new Error("16 kHz mono Web Audio 初始化失败: "+t.message);return n.name=t.name,n.agentCode="AUDIO_FIXED_TRACK_FAILED",n.retryable=!0,n.cause=t,n},t.validateOutputTrack=function(e){var t=e.getSettings();if(void 0!==t.sampleRate&&t.sampleRate!==v||void 0!==t.channelCount&&1!==t.channelCount)throw this.unsupported("浏览器音频输出格式不符合要求: "+(t.sampleRate||"unknown")+" Hz / "+(t.channelCount||"unknown")+" channel")},e}(),_=function(e,t,n,r){void 0===n&&(n={}),void 0===r&&(r=w);try{var i=function(i,s){try{var a=function(){function i(i){var s=new Uint8Array(i),a=Array.from(s.slice(0,r)),u=t instanceof Blob?t.type:n.type;console.log(e,o({},n,{size:s.byteLength,type:u,previewLength:a.length,bytes:a,hex:a.map(P).join(" ")}))}return t instanceof Blob?Promise.resolve(t.arrayBuffer()).then(i):i(ArrayBuffer.isView(t)?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength):t)}()}catch(e){return s(e)}return a&&a.then?a.then(void 0,s):a}(0,function(t){console.warn(e,"failed to read audio chunk",t)});return Promise.resolve(i&&i.then?i.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},w=64;function P(e){return e.toString(16).padStart(2,"0")}var T=new WeakMap,k=new WeakMap;function C(e){return e.audioSession}function O(e,t){try{return e.type=t,e.type===t}catch(e){return!1}}function D(){var e=globalThis.performance;return e&&Number.isFinite(e.timeOrigin)&&"function"==typeof e.now?e.timeOrigin+e.now():Date.now()}var I=/*#__PURE__*/function(){function e(e,t){void 0===t&&(t=D),this.timecodeScale=null,this.firstTimecode=null,this.lastTimecode=null,this.lastObservedAt=null,this.lastTimestamp=null,this.chunkMs=e,this.now=t,this.startedAt=t()}return e.prototype.resolve=function(e){var t=this.now(),n=Number.isFinite(e)&&e>=0;if(n&&null===this.firstTimecode&&(this.firstTimecode=e),n&&null===this.timecodeScale&&null!==this.lastTimecode&&e>this.lastTimecode){var r=e-this.lastTimecode,i=null===this.lastObservedAt?0:t-this.lastObservedAt,o=i>=this.chunkMs/4?i:this.chunkMs,s=Math.abs(r-o),a=Math.abs(1e3*r-o);this.timecodeScale=a<s?1e3:1}var u,c=t-this.chunkMs,l=n&&null!==this.firstTimecode?e-this.firstTimecode:null;null!==l&&l>=0&&(null!==this.timecodeScale||0===l)&&(c=this.startedAt+l*(null!=(u=this.timecodeScale)?u:1)),null!==this.lastTimestamp&&(c=Math.max(c,this.lastTimestamp+this.chunkMs));var h=Math.max(Math.round(this.startedAt),Math.round(c));return this.lastTimecode=n?e:this.lastTimecode,this.lastObservedAt=t,this.lastTimestamp=h,h},e}();function M(e,t){try{var n=e()}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}var N=2e4;function F(e){return{codec:"opus",sampleRate:e.sampleRate,numberOfChannels:e.channels,bitrate:e.bitrate,opus:{format:"opus",frameDuration:N}}}var U=/*#__PURE__*/function(){function e(e){void 0===e&&(e={}),this.encoder=null,this.isInitialized=!1,this.pendingEncode=null,this.timestamp=0,this.config=o({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600},e)}e.isSupported=function(){try{return"undefined"==typeof AudioEncoder?Promise.resolve(!1):Promise.resolve(M(function(){return Promise.resolve(AudioEncoder.isConfigSupported(F({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600}))).then(function(e){var t;return!0===e.supported&&(null==(t=e.config)||null==(t=t.opus)?void 0:t.frameDuration)===N})},function(){return!1}))}catch(e){return Promise.reject(e)}};var t=e.prototype;return t.init=function(){try{var e=this;return e.isInitialized||(e.encoder=e.createEncoder(),e.isInitialized=!0),Promise.resolve()}catch(e){return Promise.reject(e)}},t.encode=function(e){try{var t=this;if(!t.isInitialized||!t.encoder)return Promise.reject(new Error("WebCodecOpusEncoder 未初始化"));if(t.pendingEncode)return Promise.reject(new Error("WebCodecs Opus 编码器仍在处理上一音频块"));var n=new Int16Array(e),r=t.timestamp,i=Math.round(1e6*e.length/t.config.sampleRate),o=r+i,s=i/N;if(!Number.isInteger(s))return Promise.reject(new Error("PCM 音频块无法按 20ms Opus packet 完整分包"));var a=new AudioData({format:"s16",sampleRate:t.config.sampleRate,numberOfFrames:n.length,numberOfChannels:t.config.channels,timestamp:r,data:n}),u=new Promise(function(e,n){var i=globalThis.setTimeout(function(){t.failPending(new Error("WebCodecs Opus 编码输出超过 2 秒"))},2e3);t.pendingEncode={startTimestampUs:r,endTimestampUs:o,expectedFrameCount:s,chunks:[],resolve:e,reject:n,timeoutId:i}});try{t.encoder.encode(a),t.timestamp=o}catch(e){t.failPending(e instanceof Error?e:new Error("WebCodecs Opus 编码失败"))}finally{a.close()}return Promise.resolve(u)}catch(e){return Promise.reject(e)}},t.reset=function(){if(this.timestamp=0,this.failPending(new Error("WebCodecs Opus 编码已重置")),this.encoder){try{this.encoder.close()}catch(e){}this.encoder=this.createEncoder()}},t.destroy=function(){try{var e=function(){t.encoder=null,t.isInitialized=!1},t=this,n=t.encoder,r=function(){if(n){var e=function(){t.failPending(new Error("WebCodecs Opus 编码器已销毁"));try{n.close()}catch(e){}},r=M(function(){return Promise.resolve(n.flush()).then(function(){})},function(){});return r&&r.then?r.then(e):e()}}();return Promise.resolve(r&&r.then?r.then(e):e())}catch(e){return Promise.reject(e)}},t.createEncoder=function(){var e,t=this;return(e=new AudioEncoder({output:function(n){t.encoder===e&&t.handleOutput(n)},error:function(n){if(t.encoder===e){var r=n instanceof Error?n:new Error("WebCodecs Opus 编码失败");(globalThis.avatarSDKLogger||console).error("[WebCodecOpusEncoder] 编码错误:",r),t.failPending(r)}}})).configure(F(this.config)),e},t.handleOutput=function(e){var t=this.pendingEncode;if(t)if(e.timestamp<t.startTimestampUs||e.timestamp>=t.endTimestampUs||null!==e.duration&&e.duration!==N)this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频"));else if(t.chunks.push(e),t.chunks.length>t.expectedFrameCount)this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频"));else if(!(t.chunks.length<t.expectedFrameCount)){var n=t.chunks.map(function(e,n){var r,i,o=new Uint8Array(e.byteLength);e.copyTo(o);var s=null!=(r=null==(i=t.chunks[n+1])?void 0:i.timestamp)?r:t.endTimestampUs;return{data:o,durationMs:(e.duration&&e.duration>0?e.duration:Math.max(1,s-e.timestamp))/1e3}}),r=n.reduce(function(e,t){return e+t.durationMs},0);n.some(function(e){return 20!==e.durationMs})||r!==(t.endTimestampUs-t.startTimestampUs)/1e3?this.failPending(new Error("WebCodecs Opus 未按 20ms 分包,无法生成固定 100ms AU 音频")):(globalThis.clearTimeout(t.timeoutId),this.pendingEncode=null,t.resolve(n))}},t.failPending=function(e){var t=this.pendingEncode;t&&(globalThis.clearTimeout(t.timeoutId),this.pendingEncode=null,t.reject(e))},e}(),B=/*#__PURE__*/function(){function e(e){void 0===e&&(e=16e3),this.chunks=[],this.hasHeader=!1,this.clusterTimestamp=0,this.frameDuration=100,this.sampleRate=e}var t=e.prototype;return t.writeHeader=function(){if(!this.hasHeader){var e=this.buildEBMLHeader(),t=this.buildSegmentInfo(),n=this.buildOpusTracks();this.chunks.push(e),this.chunks.push(new Uint8Array([24,83,128,103,1,255,255,255,255,255,255,255])),this.chunks.push(t),this.chunks.push(n),this.hasHeader=!0,this.clusterTimestamp=0}},t.feedOpusFrame=function(e,t){void 0===t&&(t=this.frameDuration),this.hasHeader||this.writeHeader();var n=this.buildCluster(Math.round(this.clusterTimestamp),e);this.chunks.push(n),this.clusterTimestamp+=t},t.flush=function(){if(0===this.chunks.length)return new ArrayBuffer(0);for(var e,t=this.chunks.reduce(function(e,t){return e+t.length},0),n=new Uint8Array(t),r=0,o=i(this.chunks);!(e=o()).done;){var s=e.value;n.set(s,r),r+=s.length}return this.chunks=[],n.buffer},t.reset=function(){this.chunks=[],this.hasHeader=!1,this.clusterTimestamp=0},t.encodeVINT=function(e,t){if(void 0!==t){for(var n=new Uint8Array(t),r=t-1;r>=0;r--)n[r]=255&e,e>>>=8;return n[0]|=1<<8-t,n}if(e<127)return new Uint8Array([128|e]);if(e<16383)return new Uint8Array([64|e>>8,255&e]);if(e<2097151)return new Uint8Array([32|e>>16,e>>8&255,255&e]);if(e<268435455)return new Uint8Array([16|e>>24,e>>16&255,e>>8&255,255&e]);throw new Error("VINT value too large: "+e)},t.encodeID=function(e){return e<=255?new Uint8Array([e]):e<=65535?new Uint8Array([e>>8,255&e]):e<=16777215?new Uint8Array([e>>16,e>>8&255,255&e]):new Uint8Array([e>>>24,e>>16&255,e>>8&255,255&e])},t.encodeUint=function(e){if(0===e)return new Uint8Array([0]);for(var t=[],n=e;n>0;)t.unshift(255&n),n=Math.floor(n/256);return new Uint8Array(t)},t.encodeString=function(e){return(new TextEncoder).encode(e)},t.encodeFloat32=function(e){var t=new ArrayBuffer(4);return new DataView(t).setFloat32(0,e,!1),new Uint8Array(t)},t.encodeElement=function(e,t){var n=this.encodeID(e),r=this.encodeVINT(t.length),i=new Uint8Array(n.length+r.length+t.length);return i.set(n,0),i.set(r,n.length),i.set(t,n.length+r.length),i},t.encodeUintElement=function(e,t){return this.encodeElement(e,this.encodeUint(t))},t.encodeStringElement=function(e,t){return this.encodeElement(e,this.encodeString(t))},t.encodeFloat32Element=function(e,t){return this.encodeElement(e,this.encodeFloat32(t))},t.concatArrays=function(e){for(var t,n=e.reduce(function(e,t){return e+t.length},0),r=new Uint8Array(n),o=0,s=i(e);!(t=s()).done;){var a=t.value;r.set(a,o),o+=a.length}return r},t.buildEBMLHeader=function(){var e=this.concatArrays([this.encodeUintElement(17030,1),this.encodeUintElement(17143,1),this.encodeUintElement(17138,4),this.encodeUintElement(17139,8),this.encodeStringElement(17026,"webm"),this.encodeUintElement(17031,4),this.encodeUintElement(17029,2)]);return this.encodeElement(440786851,e)},t.buildSegmentInfo=function(){var e=this.concatArrays([this.encodeUintElement(2807729,1e6),this.encodeStringElement(19840,"xmov-avatar-sdk"),this.encodeStringElement(22337,"xmov-avatar-sdk")]);return this.encodeElement(357149030,e)},t.buildOpusTracks=function(){var e=new Uint8Array([79,112,117,115,72,101,97,100,1,1,0,0,128,62,0,0,0,0,0]),t=this.concatArrays([this.encodeFloat32Element(181,this.sampleRate),this.encodeUintElement(159,1)]),n=this.concatArrays([this.encodeUintElement(215,1),this.encodeUintElement(29637,1),this.encodeUintElement(131,2),this.encodeUintElement(156,0),this.encodeStringElement(2274716,"und"),this.encodeStringElement(134,"A_OPUS"),this.encodeElement(25506,e),this.encodeUintElement(22186,0),this.encodeUintElement(22203,8e7),this.encodeElement(225,t)]),r=this.encodeElement(174,n);return this.encodeElement(374648427,r)},t.buildCluster=function(e,t){var n=this.encodeUintElement(231,e),r=this.encodeVINT(1),i=new Uint8Array([0,0]),o=new Uint8Array([128]),s=this.concatArrays([r,i,o,t]),a=this.encodeElement(163,s),u=this.concatArrays([n,a]);return this.encodeElement(524531317,u)},e}(),x=/*#__PURE__*/function(){function e(){this.opusEncoder=new U({sampleRate:16e3,channels:1,bitrate:24e3,frameSize:1600}),this.muxer=new B(16e3),this.queue=Promise.resolve(),this.generation=0,this.destroyed=!1,this.pendingBlocks=0}e.isSupported=function(){return U.isSupported()};var t=e.prototype;return t.init=function(){try{return Promise.resolve(this.opusEncoder.init()).then(function(){})}catch(e){return Promise.reject(e)}},t.encode=function(e){try{var t=this;if(1600!==e.length)throw new Error("PCM 音频块必须为 1600 samples,实际为 "+e.length);if(t.pendingBlocks>=20)throw new Error("PCM/Opus 编码队列超过 2 秒");t.pendingBlocks+=1;var n=t.generation,r=new Int16Array(e),o=t.queue.then(function(){try{return t.destroyed||n!==t.generation?Promise.resolve(new ArrayBuffer(0)):Promise.resolve(t.opusEncoder.encode(r)).then(function(e){if(t.destroyed||n!==t.generation)return new ArrayBuffer(0);for(var r,o=i(e);!(r=o()).done;){var s=r.value;t.muxer.feedOpusFrame(s.data,s.durationMs)}return t.muxer.flush()})}catch(e){return Promise.reject(e)}}).finally(function(){t.pendingBlocks-=1});return t.queue=o.then(function(){},function(){}),Promise.resolve(o)}catch(e){return Promise.reject(e)}},t.reset=function(){var e=this,t=++this.generation;this.queue=this.queue.then(function(){e.destroyed||t!==e.generation||(e.opusEncoder.reset(),e.muxer.reset())})},t.destroy=function(){try{var e=this;return e.destroyed=!0,e.generation+=1,Promise.resolve(e.opusEncoder.destroy()).then(function(){return Promise.resolve(e.queue).then(function(){e.muxer.reset()})})}catch(e){return Promise.reject(e)}},e}(),W="audio/webm;codecs=opus";function L(e,t){try{var n=e()}catch(e){return t(!0,e)}return n&&n.then?n.then(t.bind(null,!1),t.bind(null,!0)):t(!1,n)}var j=16e3,G="agent-pcm-capture-processor",z="\nclass AgentPcmCaptureProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffer = new Float32Array(1600);\n this.bufferIndex = 0;\n this.sequence = 0;\n this.port.onmessage = (event) => {\n if (event.data?.type === 'flush') {\n this.emitBlock(true);\n this.port.postMessage({ type: 'flushed' });\n }\n };\n }\n\n emitBlock(padPartial = false) {\n if (this.bufferIndex === 0 || (!padPartial && this.bufferIndex < 1600)) return;\n const pcm = new Int16Array(1600);\n for (let index = 0; index < this.bufferIndex; index += 1) {\n const sample = Math.max(-1, Math.min(1, this.buffer[index]));\n pcm[index] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n }\n this.port.postMessage(\n { type: 'frame', pcm: pcm.buffer, sequence: this.sequence++ },\n [pcm.buffer],\n );\n this.buffer.fill(0);\n this.bufferIndex = 0;\n }\n\n process(inputs, outputs) {\n for (const output of outputs) {\n for (const channel of output) channel.fill(0);\n }\n const channels = inputs[0];\n if (!channels?.length || !channels[0]?.length) return true;\n for (let frame = 0; frame < channels[0].length; frame += 1) {\n let sample = 0;\n for (let channel = 0; channel < channels.length; channel += 1) {\n sample += channels[channel][frame] || 0;\n }\n this.buffer[this.bufferIndex++] = sample / channels.length;\n if (this.bufferIndex === 1600) this.emitBlock();\n }\n return true;\n }\n}\nregisterProcessor('"+G+"', AgentPcmCaptureProcessor);\n",V=/*#__PURE__*/function(){function e(e){var t,n;this.stream=null,this.recordingStream=null,this.audioTransformer=null,this.mediaRecorder=null,this.pcmAudioContext=null,this.pcmSource=null,this.pcmWorklet=null,this.pcmEncoder=null,this.pcmEncodeQueue=Promise.resolve(),this.pcmStartedAt=0,this.pcmGeneration=0,this.resolvePcmFlush=null,this.startGeneration=0,this.starting=!1,this.hasAudioSessionCapture=!1,this.options=e,this.pendingInputStream=null!=(t=e.inputStream)?t:null,this.usesProvidedInput=Boolean(e.inputStream),this.metadata=o({},m,{chunkMs:(null==(n=e.audio)?void 0:n.chunkMs)||m.chunkMs})}var t=e.prototype;return t.getAudioMetadata=function(){return this.metadata},t.start=function(){try{var e=this;if(e.stream||e.starting)return Promise.resolve();var t=++e.startGeneration;return e.starting=!0,Promise.resolve(L(function(){return function(n,r){try{var i=function(){function n(n){function a(n){var r;function i(n){if(r)return n;var i=new b({onError:function(t){var n=t instanceof Error?t:new Error("16 kHz mono 音频处理失败");n.name="MediaRecorderError",null==e.options.onError||e.options.onError(n)}});return e.audioTransformer=i,Promise.resolve(i.start(a)).then(function(n){e.recordingStream=n,e.assertStartActive(t);var r=e.recordingStream.getAudioTracks()[0],i=null==r?void 0:r.getSettings();e.metadata=o({},e.metadata,{sampleRate:(null==i?void 0:i.sampleRate)||j,channels:(null==i?void 0:i.channelCount)||1}),e.startWebMRecorder(s),null==e.options.onMetadata||e.options.onMetadata(e.metadata)})}e.assertStartActive(t);var a=e.stream.getAudioTracks()[0];if(!a)throw new Error("麦克风未返回音频轨道");var u=function(){if(e.options.usePcmWebCodecs)return Promise.resolve(e.startPcmWebMRecorder(e.stream)).then(function(){e.assertStartActive(t),e.metadata=o({},e.metadata,{sampleRate:j,channels:1,chunkMs:100}),null==e.options.onMetadata||e.options.onMetadata(e.metadata),r=1})}();return u&&u.then?u.then(i):i(u)}e.assertStartActive(t);var u=function(){if(!e.stream){if(e.usesProvidedInput)throw r?e.cancelled():new Error("ASR 输入流已释放");return e.hasAudioSessionCapture=function(e){var t,n;void 0===e&&(e=navigator);var r=C(e);if(!r)return!1;var i=T.get(r),o=null!=(t=null==i?void 0:i.previousType)?t:r.type;return!!O(r,"play-and-record")&&(T.set(r,{count:(null!=(n=null==i?void 0:i.count)?n:0)+1,previousType:o}),!0)}(),Promise.resolve(i.getUserMedia({audio:{sampleRate:{ideal:j},channelCount:{ideal:1},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}})).then(function(t){e.stream=t})}}();return u&&u.then?u.then(a):a()}var r=e.pendingInputStream;e.stream=null!=r?r:null,e.pendingInputStream=null;var i=navigator.mediaDevices;if(!(e.stream||null!=i&&i.getUserMedia))throw new Error("当前浏览器不支持麦克风采集");var s=globalThis.MediaRecorder,a=function(){if(e.options.usePcmWebCodecs)return Promise.resolve(x.isSupported()).then(function(t){if(!t)throw e.webCodecsOpusUnsupported()});if(null==s||null==s.isTypeSupported||!s.isTypeSupported(W))throw e.webMOpusUnsupported()}();return a&&a.then?a.then(n):n()}()}catch(e){return r(e)}return i&&i.then?i.then(void 0,r):i}(0,function(n){var r=t!==e.startGeneration;return Promise.resolve(e.stop()).then(function(){var t=r?e.cancelled():n instanceof Error?n:new Error("麦克风启动失败");throw"AUDIO_FIXED_TRACK_CANCELLED"!==t.agentCode&&(null==e.options.onError||e.options.onError(t)),t})})},function(n,r){if(e.startGeneration===t&&(e.starting=!1),n)throw r;return r}))}catch(e){return Promise.reject(e)}},t.stop=function(){try{var e=this;e.startGeneration+=1,e.starting=!1;var t=L(function(){function t(){var t;e.recordingStream=null,e.stream&&!n&&e.stream.getTracks().forEach(function(e){return e.stop()}),e.stream=null,null==(t=e.pendingInputStream)||t.getTracks().forEach(function(e){return e.stop()}),e.pendingInputStream=null}var n=e.audioTransformer,r=L(function(){return Promise.resolve(null==n?void 0:n.drain()).then(function(){})},function(t,r){return Promise.resolve(e.stopPcmWebMRecorder()).then(function(){return Promise.resolve(e.stopMediaRecorder()).then(function(){return Promise.resolve(null==n?void 0:n.stop()).then(function(){if(e.audioTransformer=null,t)throw r;return r})})})});return r&&r.then?r.then(t):t()},function(t,n){if(e.hasAudioSessionCapture&&(e.hasAudioSessionCapture=!1,function(e){void 0===e&&(e=navigator);var t=C(e);if(!t)return!1;var n=T.get(t);if(!n)return function(e){void 0===e&&(e=navigator);var t=C(e);if(!t)return!1;var n=T.get(t);return O(t,null!=n&&n.count||"play-and-record"===t.type?"play-and-record":"playback")}(e);if(n.count-=1,n.count>0)return O(t,"play-and-record");T.delete(t);var r="play-and-record"===n.previousType?"play-and-record":"playback";O(t,r)&&"playback"===r&&function(e){var t=k.get(e);if(t)for(var n=0,r=[].concat(t);n<r.length;n++){var i=r[n];try{i()}catch(e){}}}(t)}()),t)throw n;return n});return Promise.resolve(t&&t.then?t.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},t.startWebMRecorder=function(e){var t,n=this;if(!this.recordingStream)throw new Error("16 kHz mono 音频流未就绪");try{t=new e(this.recordingStream,{mimeType:W,audioBitsPerSecond:24e3})}catch(e){if(e instanceof Error&&"NotSupportedError"===e.name)throw this.webMOpusUnsupported(e);throw e}var r=new I(this.metadata.chunkMs);t.ondataavailable=function(e){if(e.data.size>0){var i,o=r.resolve(e.timecode);null==(i=globalThis.avatarSDKLogger)||null==i.log||i.log("[Agent][Microphone]","audio chunk",{size:e.data.size,type:e.data.type,chunkMs:n.metadata.chunkMs,sampleRate:n.metadata.sampleRate,channels:n.metadata.channels,recorderState:t.state,timecode:e.timecode}),n.options.debugAudioChunks&&_("[Agent][Microphone] nearend WebM/Opus chunk",e.data,{chunkMs:n.metadata.chunkMs,sampleRate:n.metadata.sampleRate,channels:n.metadata.channels,recorderState:t.state,timecode:e.timecode}),n.options.onFrame(e.data,o)}},t.onerror=function(e){var t=e.error,r=new Error(t instanceof Error?t.message:"WebM/Opus 麦克风录制失败");r.name="MediaRecorderError",null==n.options.onError||n.options.onError(r)},this.mediaRecorder=t;try{t.start(this.metadata.chunkMs)}catch(e){if(e instanceof Error&&"NotSupportedError"===e.name)throw this.webMOpusUnsupported(e);throw e}},t.assertStartActive=function(e){if(e!==this.startGeneration)throw this.cancelled()},t.cancelled=function(){var e=new Error("麦克风启动已取消");return e.name="AbortError",e.agentCode="AUDIO_FIXED_TRACK_CANCELLED",e.retryable=!0,e},t.webMOpusUnsupported=function(e){var t=new Error("当前浏览器不支持 audio/webm;codecs=opus");return t.name="NotSupportedError",t.agentCode="AUDIO_WEBM_OPUS_UNSUPPORTED",t.retryable=!1,t.cause=e,t},t.webCodecsOpusUnsupported=function(e){var t=new Error("当前浏览器不支持 WebCodecs AudioEncoder Opus");return t.name="NotSupportedError",t.agentCode="AUDIO_WEBCODECS_OPUS_UNSUPPORTED",t.retryable=!1,t.cause=e,t},t.startPcmWebMRecorder=function(e){try{var t=this,n=globalThis,r=globalThis.AudioContext||n.webkitAudioContext;if(!r||void 0===globalThis.AudioWorkletNode)throw t.webCodecsOpusUnsupported(new Error("AudioWorklet 不可用"));var i=new x;return Promise.resolve(i.init()).then(function(){function n(n){function r(){function n(){if("running"!==o.state)throw t.audioContextSuspended();var n=o.createMediaStreamSource(e),r=new AudioWorkletNode(o,G,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[1]}),s=++t.pcmGeneration;t.pcmSource=n,t.pcmWorklet=r,t.pcmEncodeQueue=Promise.resolve(),t.pcmStartedAt=t.monotonicEpochNow(),r.port.onmessage=function(e){var n,r;if("flushed"===(null==(n=e.data)?void 0:n.type))return null==t.resolvePcmFlush||t.resolvePcmFlush(),void(t.resolvePcmFlush=null);if("frame"===(null==(r=e.data)?void 0:r.type)&&e.data.pcm instanceof ArrayBuffer){var o=t.pcmStartedAt+100*Number(e.data.sequence||0),a=new Int16Array(e.data.pcm);t.pcmEncodeQueue=t.pcmEncodeQueue.then(function(){try{return Promise.resolve(i.encode(a)).then(function(n){if(s===t.pcmGeneration&&0!==n.byteLength){var r=new Blob([n],{type:W});t.options.debugAudioChunks&&_("[Agent][Microphone] nearend PCM/WebCodecs chunk",r,{chunkMs:100,sampleRate:j,channels:1,sequence:e.data.sequence}),t.options.onFrame(r,o)}})}catch(e){return Promise.reject(e)}}).catch(function(e){var n=e instanceof Error?e:new Error("PCM/Opus 麦克风编码失败");n.name="AudioEncoderError",null==t.options.onError||t.options.onError(n)})}},n.connect(r),r.connect(o.destination)}var r=function(){if("suspended"===o.state)return Promise.resolve(o.resume()).then(function(){})}();return r&&r.then?r.then(n):n()}t.pcmAudioContext=o,t.pcmEncoder=i;var s=URL.createObjectURL(new Blob([z],{type:"application/javascript"})),a=L(function(){return Promise.resolve(o.audioWorklet.addModule(s)).then(function(){})},function(e,t){if(URL.revokeObjectURL(s),e)throw t;return t});return a&&a.then?a.then(r):r()}var o=new r({sampleRate:j}),s=function(){if(o.sampleRate!==j)return Promise.resolve(i.destroy()).then(function(){return Promise.resolve(o.close().catch(function(){})).then(function(){throw t.webCodecsOpusUnsupported(new Error("浏览器无法创建 16000 Hz AudioContext"))})})}();return s&&s.then?s.then(n):n()})}catch(e){return Promise.reject(e)}},t.stopPcmWebMRecorder=function(){try{var e=function(){return Promise.resolve(t.pcmEncodeQueue).then(function(){function e(){return Promise.resolve(null==o?void 0:o.destroy()).then(function(){t.pcmWorklet=null,t.pcmSource=null,t.pcmAudioContext=null,t.pcmEncoder=null,t.pcmEncodeQueue=Promise.resolve()})}t.pcmGeneration+=1,t.resolvePcmFlush=null,n&&(n.port.onmessage=null,n.disconnect(),n.port.close());var r=function(){if(i&&"closed"!==i.state)return Promise.resolve(i.close().catch(function(){})).then(function(){})}();return r&&r.then?r.then(e):e()})},t=this,n=t.pcmWorklet,r=t.pcmSource,i=t.pcmAudioContext,o=t.pcmEncoder;if(!n&&!i&&!o)return Promise.resolve();null==r||r.disconnect();var s=function(){if(n)return Promise.resolve(Promise.race([new Promise(function(e){t.resolvePcmFlush=function(){return e(!0)},n.port.postMessage({type:"flush"})}),new Promise(function(e){return globalThis.setTimeout(function(){return e(!1)},100)})])).then(function(e){e||(t.resolvePcmFlush=null,n.port.onmessage=null)})}();return Promise.resolve(s&&s.then?s.then(e):e())}catch(e){return Promise.reject(e)}},t.monotonicEpochNow=function(){var e=globalThis.performance;return e&&Number.isFinite(e.timeOrigin)?Math.round(e.timeOrigin+e.now()):Date.now()},t.audioContextSuspended=function(){var e=new Error("AudioContext 未运行,请在用户操作后重试");return e.name="NotAllowedError",e.agentCode="AUDIO_CONTEXT_SUSPENDED",e.retryable=!0,e},t.stopMediaRecorder=function(){try{var e=this.mediaRecorder;if(this.mediaRecorder=null,!e)return Promise.resolve();var t="inactive"!==e.state;return Promise.resolve(new Promise(function(n){var r=!1,i=function(){r||(r=!0,globalThis.clearTimeout(s),n())},o=e.onerror,s=globalThis.setTimeout(i,1e3);if(e.onstop=i,e.onerror=function(t){null==o||o.call(e,t),i()},t)try{e.stop()}catch(e){i()}})).then(function(){e.ondataavailable=null,e.onerror=null,e.onstop=null})}catch(e){return Promise.reject(e)}},r(e,[{key:"isRecording",get:function(){return this.starting||Boolean(this.stream)||Boolean(this.pendingInputStream)}}])}(),K="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function X(e,t,n){if(!e.s){if(n instanceof H){if(!n.s)return void(n.o=X.bind(null,e,t));1&t&&(t=n.s),n=n.v}if(n&&n.then)return void n.then(X.bind(null,e,t),X.bind(null,e,2));e.s=t,e.v=n;var r=e.o;r&&r(e)}}var H=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(t,n){var r=new e,i=this.s;if(i){var o=1&i?t:n;if(o){try{X(r,1,o(this.v))}catch(e){X(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?X(r,1,t?t(i):i):n?X(r,1,n(i)):X(r,2,i)}catch(e){X(r,2,e)}},r},e}();function q(e){return e instanceof H&&1&e.s}var J=function(e){try{var t,n=function(n){var r;if(t)return n;function i(t){return r?t:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}var o=function(){if(e instanceof Blob)return Promise.resolve(e.arrayBuffer()).then(function(e){var t=new Uint8Array(e);return r=1,t})}();return o&&o.then?o.then(i):i(o)},r=function(){if(Array.isArray(e))return Promise.resolve(Promise.all(e.map(J))).then(function(e){for(var n,r=new Uint8Array(e.reduce(function(e,t){return e+t.byteLength},0)),o=0,s=i(e);!(n=s()).done;){var a=n.value;r.set(a,o),o+=a.byteLength}return t=1,r})}();return Promise.resolve(r&&r.then?r.then(n):n(r))}catch(e){return Promise.reject(e)}},Y=new Uint8Array([26,69,223,163]);function Q(e,t){var n=globalThis.avatarSDKLogger;null==n||null==n.log||n.log("[Agent][AudioUplink]",e,t)}var $=/*#__PURE__*/function(){function e(e){this.connectionStartedAt=null,this.connectionGeneration=0,this.sendChain=Promise.resolve(),this.failed=!1,this.pendingFarend=new Map,this.pendingNearend=new Map,this.closedNearendBuckets=new Set,this.lastTimestampByStream=new Map,this.lastSentTimestampByStream=new Map,this.pendingWebmPrefixByStream=new Map,this.farendStreamState="unknown",this.options=e}var t=e.prototype;return t.reset=function(e){void 0===e&&(e=null),this.connectionGeneration+=1,this.connectionStartedAt=e,this.pendingFarend.clear(),this.pendingNearend.clear(),this.closedNearendBuckets.clear(),this.lastTimestampByStream.clear(),this.lastSentTimestampByStream.clear(),this.pendingWebmPrefixByStream.clear(),this.farendStreamState="unknown",this.failed=!1,this.sendChain=Promise.resolve()},t.startInput=function(){this.failed=!1,this.pendingFarend.clear(),this.pendingNearend.clear(),this.closedNearendBuckets.clear(),this.pendingWebmPrefixByStream.clear(),this.farendStreamState="unknown"},t.clearFarend=function(){this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="unknown"},t.offerFarend=function(e){var t;if(!1!==e.isFirstChunk||"ready"===this.farendStreamState){var n=this.normalizeBlock(2,e);if(n){e.isFirstChunk&&(this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="ready");var r=null!=(t=this.pendingFarend.get(n.frameKey))?t:[];r.push(n),this.pendingFarend.set(n.frameKey,r),Q("farend.offer",{tsMs:n.tsMs,frameKey:n.frameKey,isFirstChunk:Boolean(n.isFirstChunk),pendingNearend:[].concat(this.pendingNearend.keys())}),this.flushOlderNearend(n.frameKey),this.prune(n.frameKey)}else e.isFirstChunk&&this.abandonFarendStream()}else Q("farend.drop",{reason:"awaiting_webm_header",timestamp:e.timestamp,isFirstChunk:!1})},t.offerNearend=function(e){var t,n=this.normalizeBlock(1,e);if(n&&!this.closedNearendBuckets.has(n.frameKey)){var r=null!=(t=this.pendingNearend.get(n.frameKey))?t:[];r.push(n),this.pendingNearend.set(n.frameKey,r),this.flushExpiredNearend(n.frameKey),this.prune(n.frameKey)}},t.drain=function(){for(var e,t=i([].concat(this.pendingNearend.keys()).sort(function(e,t){return e-t}));!(e=t()).done;)this.flushBucket(e.value,!0);return this.sendChain},t.normalizeBlock=function(e,t){var n=this.connectionStartedAt;if(null===n||!Number.isFinite(t.timestamp))return null;var r=Math.max(0,Math.floor(t.timestamp-n)),i=Math.floor(r/100),s=this.lastTimestampByStream.get(e);return void 0!==s&&r<=s?null:(this.lastTimestampByStream.set(e,r),o({},t,{streamId:e,tsMs:r,frameKey:i}))},t.enqueue=function(e){var t=this,n=this;if(!this.failed){var r=this.connectionGeneration;this.sendChain=this.sendChain.then(function(){try{if(n.failed)return Promise.resolve();var t=function(e,t){if("function"==typeof e[K]){var n,r,i,o=function(e){try{for(;!(n=s.next()).done;)if((e=t(n.value))&&e.then){if(!q(e))return void e.then(o,i||(i=X.bind(null,r=new H,2)));e=e.v}r?X(r,1,e):r=e}catch(e){X(r||(r=new H),2,e)}},s=e[K]();if(o(),s.return){var a=function(e){try{n.done||s.return()}catch(e){}return e};if(r&&r.then)return r.then(a,function(e){throw a(e)});a()}return r}if(!("length"in e))throw new TypeError("Object is not iterable");for(var u=[],c=0;c<e.length;c++)u.push(e[c]);return function(e,t){var n,r,i=-1;return function o(s){try{for(;++i<e.length;)if((s=t(i))&&s.then){if(!q(s))return void s.then(o,r||(r=X.bind(null,n=new H,2)));s=s.v}n?X(n,1,s):n=s}catch(e){X(n||(n=new H),2,e)}}(),n}(u,function(e){return t(u[e])})}(e,function(e){var t;return Promise.resolve(J(null!=(t=e.dataParts)?t:e.data)).then(function(t){if(!n.failed&&r===n.connectionGeneration&&null!==n.connectionStartedAt&&0!==t.byteLength){2===e.streamId&&e.isFirstChunk&&n.pendingWebmPrefixByStream.delete(2);var i=n.coalesceSplitWebmMagic(e.streamId,t);if(i){var o=n.lastSentTimestampByStream.get(e.streamId);void 0!==o&&e.tsMs<=o||(n.options.sendBinary(function(e,t,n){if(1!==e&&2!==e)throw new Error("AU stream_id 无效: "+e);if(!Number.isFinite(t)||t<0||t>4294967295)throw new Error("AU ts_ms 无效: "+t);var r=n instanceof ArrayBuffer?new Uint8Array(n):new Uint8Array(n.buffer,n.byteOffset,n.byteLength),i=new ArrayBuffer(8+r.byteLength),o=new DataView(i);return o.setUint8(0,65),o.setUint8(1,85),o.setUint8(2,1),o.setUint8(3,e),o.setUint32(4,Math.floor(t),!1),new Uint8Array(i,8).set(r),i}(e.streamId,e.tsMs,i)),n.lastSentTimestampByStream.set(e.streamId,e.tsMs),Q("frame.send",{streamId:e.streamId,tsMs:e.tsMs,bytes:i.byteLength}))}}})});return Promise.resolve(t&&t.then?t.then(function(){}):void 0)}catch(e){return Promise.reject(e)}}).catch(function(e){if(r===t.connectionGeneration){t.failed=!0,t.pendingFarend.clear(),t.pendingNearend.clear();var n=e instanceof Error?e:new Error("AU 音频上行失败");null==t.options.onError||t.options.onError(n)}})}},t.coalesceSplitWebmMagic=function(e,t){var n=this.pendingWebmPrefixByStream.get(e);if(n){var r=new Uint8Array(n.byteLength+t.byteLength);r.set(n),r.set(t,n.byteLength),this.pendingWebmPrefixByStream.delete(e),t=r}return t.byteLength<Y.byteLength&&t.every(function(e,t){return e===Y[t]})?(this.pendingWebmPrefixByStream.set(e,t.slice()),null):t},t.flushOlderNearend=function(e){for(var t,n=i([].concat(this.pendingNearend.keys()).sort(function(e,t){return e-t}));!(t=n()).done;){var r=t.value;if(r>=e)break;this.flushBucket(r,!0)}},t.flushExpiredNearend=function(e){this.flushOlderNearend(e-1)},t.flushBucket=function(e,t){void 0===t&&(t=!1);var n=this.takeNearend(e);if(n){var r=e-1,i=this.pendingFarend.has(e)||t&&this.pendingFarend.has(r)?this.takeFarendThrough(e):null;this.closedNearendBuckets.add(e),Q("bucket.flush",{nearendFrameKey:e,pairedFarend:Boolean(i),pendingFarend:[].concat(this.pendingFarend.keys())}),this.enqueue(i?[i,n]:[n])}},t.takeNearend=function(e){var t=this.pendingNearend.get(e);return this.pendingNearend.delete(e),null!=t&&t.length?o({},t[0],{dataParts:t.flatMap(function(e){var t;return null!=(t=e.dataParts)?t:[e.data]})}):null},t.takeFarendThrough=function(e){for(var t,n=[],r=i([].concat(this.pendingFarend.keys()).sort(function(e,t){return e-t}));!(t=r()).done;){var s=t.value;if(s>e)break;n.push.apply(n,this.pendingFarend.get(s)),this.pendingFarend.delete(s)}return 0===n.length?null:o({},n[n.length-1],{dataParts:n.map(function(e){return e.data}),isFirstChunk:n.some(function(e){return e.isFirstChunk})})},t.abandonFarendStream=function(){Q("farend.drop",{reason:"stale_bucket_abandons_webm_stream",pendingFarend:[].concat(this.pendingFarend.keys())}),this.pendingFarend.clear(),this.pendingWebmPrefixByStream.delete(2),this.farendStreamState="awaiting-header"},t.prune=function(e){var t=e-3;[].concat(this.pendingFarend.keys()).some(function(e){return e<t})&&this.abandonFarendStream();for(var n,r=i(this.pendingNearend.keys());!(n=r()).done;){var o=n.value;o<t&&this.flushBucket(o,!0)}for(var s,a=i(this.closedNearendBuckets);!(s=a()).done;){var u=s.value;u<t&&this.closedNearendBuckets.delete(u)}},e}(),Z=["e2eServer","authToken","audio","reconnect","agentCallbacks","webSocketCtor","asr_id","asr_config","tts_config","features","extras","llm_id","brain_config","session_speak_req_id"];function ee(e,t,n){if(!e.s){if(n instanceof te){if(!n.s)return void(n.o=ee.bind(null,e,t));1&t&&(t=n.s),n=n.v}if(n&&n.then)return void n.then(ee.bind(null,e,t),ee.bind(null,e,2));e.s=t,e.v=n;var r=e.o;r&&r(e)}}var te=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(t,n){var r=new e,i=this.s;if(i){var o=1&i?t:n;if(o){try{ee(r,1,o(this.v))}catch(e){ee(r,2,e)}return r}return this}return this.o=function(e){try{var i=e.v;1&e.s?ee(r,1,t?t(i):i):n?ee(r,1,n(i)):ee(r,2,i)}catch(e){ee(r,2,e)}},r},e}();function ne(e){return e instanceof te&&1&e.s}function re(e,t,n){for(var r;;){var i=e();if(ne(i)&&(i=i.v),!i)return o;if(i.then){r=0;break}var o=n();if(o&&o.then){if(!ne(o)){r=1;break}o=o.s}if(t){var s=t();if(s&&s.then&&!ne(s)){r=2;break}}}var a=new te,u=ee.bind(null,a,2);return(0===r?i.then(l):1===r?o.then(c):s.then(h)).then(void 0,u),a;function c(r){o=r;do{if(t&&(s=t())&&s.then&&!ne(s))return void s.then(h).then(void 0,u);if(!(i=e())||ne(i)&&!i.v)return void ee(a,1,o);if(i.then)return void i.then(l).then(void 0,u);ne(o=n())&&(o=o.v)}while(!o||!o.then);o.then(c).then(void 0,u)}function l(e){e?(o=n())&&o.then?o.then(c).then(void 0,u):c(o):ee(a,1,o)}function h(){(i=e())?i.then?i.then(l).then(void 0,u):l(i):ee(a,1,o)}}function ie(e,t){try{var n=e()}catch(e){return t(e)}return n&&n.then?n.then(void 0,t):n}function oe(e,t){try{var n=e()}catch(e){return t(!0,e)}return n&&n.then?n.then(t.bind(null,!1),t.bind(null,!0)):t(!1,n)}var se=2147483647;function ae(e){if(void 0===e)return!1;var t=JSON.stringify(e);return void 0!==t&&"{}"!==t}var ue={1006:"E2E WebSocket 异常断开:未收到 Close frame,请检查 E2EMPServer 日志或中间网络",4e3:"E2E WebSocket 路径未知",4001:"E2E Token 无效",4002:"E2E Session 不存在",4009:"E2E 配额超限",4010:"E2E 服务端主动断开"},ce=new Set([1001,1006,1011,1012,1013,1014]);function le(e,t,n){if(void 0!==n&&(!n||Array.isArray(n)||"object"!=typeof n))throw new Error("Agent "+e+" JSON Config 必须是对象");if(void 0!==t&&ae(n))throw new Error("Agent "+e+" 配置不能同时提供 ID 和 JSON Config")}function he(e,t){if(void 0!==t&&(!t||Array.isArray(t)||"object"!=typeof t))throw new Error("Agent "+e+" 必须是对象")}var de=/*#__PURE__*/function(e){function t(t){var n,r,i,s;le("ASR",t.asr_id,t.asr_config),le("TTS",void 0,t.tts_config),le("Brain",t.llm_id,t.brain_config),he("features",t.features),he("extras",t.extras);var a,u=t.e2eServer,c=t.authToken,l=t.audio,h=t.reconnect,d=t.agentCallbacks,f=t.webSocketCtor,m=t.asr_id,p=t.asr_config,v=t.tts_config,g=t.features,E=t.extras,S=t.llm_id,y=t.brain_config,R=t.session_speak_req_id,A=function(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==t.indexOf(r))continue;n[r]=e[r]}return n}(t,Z),b=A.onMessage,_=A.onRenderChange,w=A.onNetworkInfo,P=A.onSpeakStateChange,T=A.onVoiceStateChange,k=A.onAudioPlaybackData,C=function(e){var t;null==(t=a)||t.forwardFarendAudio(e),null==k||k(e)},O=null!=R?R:1,D=function(e){if(e&&ae(e)){var t=e.extra_body;if(void 0!==t&&(!t||Array.isArray(t)||"object"!=typeof t))throw new Error("Agent Brain extra_body 必须是 JSON 对象");return o({},e)}}(y),I=o({},A,{session_speak_req_id:O,sessionRequestData:o({},void 0!==m?{asr_id:m}:{},ae(p)?{asr_config:p}:{},ae(v)?{tts_config:v}:{},ae(g)?{features:g}:{},ae(E)?{extras:E}:{},void 0!==S?{llm_id:S}:{},void 0!==D?{brain_config:D}:{},{session_speak_req_id:O}),enableClientInterrupt:null==(n=A.enableClientInterrupt)||n,onMessage:function(e){var t,n;b(e),null!=(t=a)&&t.reportingInitializationFailure||null==(n=a)||n.emitError("sdk",String(e.code||"AVATAR_ERROR"),e.message||"Avatar SDK 错误",!0,e)},onRenderChange:function(e){var t;null==_||_(e),null==(t=a)||t.safeEmit(function(){return null==d||null==d.onRenderChange?void 0:d.onRenderChange(e)})},onNetworkInfo:function(e){var t;null==w||w(e),null==(t=a)||t.safeEmit(function(){return null==d||null==d.onNetworkInfo?void 0:d.onNetworkInfo(e)})},onSpeakStateChange:function(e,t){var n,r,i;null==P||P(e,t),null==(n=a)||n.safeEmit(function(){return null==d||null==d.onSpeakStateChange?void 0:d.onSpeakStateChange({state:e,clientSpeakId:t})}),["speak_start","start","started"].includes(e)&&(a&&(a.interactionPending=!0,a.voicePlaying=!0),null==(r=a)||r.emitConversation({state:"speaking"})),["speak_end","end","ended","completed","finish","finished"].includes(e)&&(null==(i=a)||i.emitConversation({state:"completed"}))},onVoiceStateChange:function(e,t,n){var r;a&&"start"===e&&(a.voicePlaying=!0),"end"===e&&(a&&(a.voicePlaying=!1),null==(r=a)||r.forwardVoiceEnd()),null==T||T(e,t,n)}},k?{onAudioPlaybackData:C}:{});return(s=e.call(this,I)||this).e2eClient=null,s.microphone=null,s.stopASRPromise=null,s.initializationPromise=null,s.rejectInitialization=null,s.initialSessionAttempt=null,s.initialSessionGeneration=0,s.initialTtsaReadySessionIds=new Set,s.initialTtsaReadyBeforeSession=!1,s.asrStartGeneration=0,s.agentState="idle",s.asrState="idle",s.agentDestroyed=!1,s.agentDestroying=!1,s.destroyPromise=null,s.suppressNextVoiceEnd=!1,s.replaySending=!1,s.farendAudioEnabled=!1,s.reconnectTimer=null,s.reconnectAttempt=0,s.reconnectInFlight=!1,s.sessionReloadFallback=!1,s.waitingForTtsaReload=!1,s.stateBeforeReconnect="ready",s.e2eSessionId="",s.currentE2EUrl="",s.serviceReconnect=null,s.serviceMigration=null,s.interactionPending=!1,s.llmPending=!1,s.llmProducedText=!1,s.directSpeakOpen=!1,s.pendingASR=!1,s.autoSendASRToLLM=!0,s.voicePlaying=!1,s.reportingInitializationFailure=!1,s.handleOnlineForReconnect=function(){s.serviceMigration||"reconnecting"!==s.agentState||s.reconnectInFlight||s.sessionReloadFallback||(s.clearReconnectTimer(),s.scheduleE2EReconnect(!0))},a=s,s.agentOptions={e2eServer:u,authToken:c,audio:l,requestedEnableAec:"boolean"==typeof(null==g||null==(r=g.speech_frontend)?void 0:r.enable_aec)?g.speech_frontend.enable_aec:void 0,callbacks:d,webSocketCtor:f,debugAudioChunks:Boolean(A.enableDebugger)},s.audioInputEnabled=null!=(i=null==l?void 0:l.inputEnabled)&&i,s.autoSendASRToLLM=!1!==(null==g?void 0:g.auto_send_asr_to_llm),s.originalOnAudioPlaybackData=k,s.playbackDataHandler=C,s.reconnectOptions=s.normalizeReconnectOptions(h),s.audioUplink=new $({sendBinary:function(e){var t;return null==(t=s.e2eClient)?void 0:t.sendBinary(e)},onError:function(e){return s.handleAudioUplinkError(e)}}),s}var n,r;r=e,(n=t).prototype=Object.create(r.prototype),n.prototype.constructor=n,s(n,r);var i=t.prototype;return i.getAgentState=function(){return this.agentState},i.getState=function(){return this.getAgentState()},i.getASRState=function(){return this.asrState},i.init=function(e){var t=this;if(void 0===e&&(e={}),this.initializationPromise)return this.initializationPromise;var n=this.initialize(e).finally(function(){t.initializationPromise===n&&(t.initializationPromise=null)});return this.initializationPromise=n,n},i.initialize=function(t){try{var n=this;n.assertNotDestroyed(),n.setAgentState("initializing");var r=new Promise(function(e,t){n.rejectInitialization=t});return r.catch(function(){}),Promise.resolve(oe(function(){return ie(function(){var i=o({},t,{onDownloadProgress:t.onDownloadProgress||function(){}});return Promise.resolve(e.prototype.initializeSession.call(n,i)).then(function(e){var t;function i(e){function t(){n.assertE2EOpen(),n.setAgentState("ready"),n.start()}n.assertNotDestroyed();var r=re(function(){return!!n.serviceMigration},void 0,function(){return Promise.resolve(n.serviceMigration.completion).then(function(){})});return r&&r.then?r.then(t):t()}if(n.assertNotDestroyed(),!e)throw new Error("XmovAvatar 初始化未返回 sessionInfo");n.applySessionFeatures(e),n.assertNotDestroyed(),n.beginInitialSession(e);var o=re(function(){return!t},void 0,function(){var e=n.initialSessionAttempt;if(!e)throw new Error("Agent 初始化缺少会话连接任务");return Promise.resolve(Promise.race([Promise.all([e.e2ePromise,e.ttsaReadyPromise]),r])).then(function(){e===n.initialSessionAttempt&&(t=1)})});return o&&o.then?o.then(i):i()})},function(e){function t(){throw e}if(n.serviceMigration&&!n.agentDestroying&&!n.agentDestroyed)throw n.failServiceMigration("E2E_MIGRATION_FAILED","E2E 更新迁移失败"),e;var r=function(){var t;if(!n.agentDestroyed&&!n.agentDestroying)return null==(t=n.e2eClient)||t.disconnect(1e3,"agent_init_failed"),n.e2eClient=null,Promise.resolve(n.cleanupBeforeInitComplete("agent_init_failed")).then(function(){try{n.setAgentState("failed")}catch(e){}n.reportingInitializationFailure=!0;try{n.reportInitializationFailure("Agent 初始化失败",e)}catch(e){}finally{n.reportingInitializationFailure=!1}try{n.emitError("sdk","AGENT_INIT_FAILED","Agent 初始化失败",!0,e)}catch(e){}n.agentDestroyed=!0})}();return r&&r.then?r.then(t):t()})},function(e,t){var r;if(n.rejectInitialization=null,n.initialSessionGeneration+=1,null==(r=n.initialSessionAttempt)||r.resolveTtsaReady(),n.initialSessionAttempt=null,n.initialTtsaReadySessionIds.clear(),n.initialTtsaReadyBeforeSession=!1,e)throw t;return t}))}catch(e){return Promise.reject(e)}},i.beginInitialSession=function(e){var t=this;this.e2eSessionId=e.session_id;var n=this.initialSessionAttempt,r=++this.initialSessionGeneration;null==n||n.resolveTtsaReady();var i=function(){},o=new Promise(function(e){i=e}),s=this.replaceE2EConnection(e.e2e_resp).catch(function(e){if(r===t.initialSessionGeneration)throw e}),a={sessionInfo:e,e2ePromise:s,ttsaReadyPromise:o,resolveTtsaReady:i};return this.initialSessionAttempt=a,this.initialTtsaReadySessionIds.delete(e.session_id)?a.resolveTtsaReady():!n&&this.initialTtsaReadyBeforeSession&&(this.initialTtsaReadyBeforeSession=!1,a.resolveTtsaReady()),s.catch(function(){}),s},i.start=function(){var t;"initializing"!==this.agentState&&"running"!==this.agentState&&("reconnecting"!==this.agentState?(this.assertE2EOpen(),e.prototype.start.call(this),this.setAgentState("running")):this.waitingForTtsaReload&&null!=(t=this.e2eClient)&&t.isOpen&&("running"===this.stateBeforeReconnect&&e.prototype.start.call(this),this.finishReconnect()))},i.onTtsaReady=function(t){if(this.rejectInitialization){var n=this.initialSessionAttempt,r=null==t?void 0:t.session_id;!n||r&&n.sessionInfo.session_id!==r?r?this.initialTtsaReadySessionIds.add(r):this.initialTtsaReadyBeforeSession=!0:n.resolveTtsaReady()}else"reconnecting"!==this.agentState?"running"===this.agentState&&e.prototype.start.call(this):this.start()},i.abortInitialization=function(e){var t;null==(t=this.rejectInitialization)||t.call(this,e)},i.stop=function(){try{var t=this;if(t.agentDestroyed)return Promise.resolve();var n="reconnecting"===t.agentState;return n&&(t.stateBeforeReconnect="stopped",t.serviceMigration&&(t.serviceMigration.previousState="stopped")),Promise.resolve(t.stopASR()).then(function(){return Promise.resolve(e.prototype.stop.call(t)).then(function(){n||t.setAgentState("stopped")})})}catch(e){return Promise.reject(e)}},i.switchInvisibleMode=function(){try{var t=this,n=t.getStatus(),r=n===c.online||n===c.visible;e.prototype.switchInvisibleMode.call(t);var i=function(){if(r)return Promise.resolve(t.stopASR()).then(function(){})}();return Promise.resolve(i&&i.then?i.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},i.destroy=function(e){var t=this;return void 0===e&&(e="js_sdk_exit"),this.destroyPromise?this.destroyPromise:this.agentDestroyed?("destroyed"!==this.agentState&&this.setAgentState("destroyed"),Promise.resolve()):(this.agentDestroying=!0,this.destroyPromise=Promise.resolve().then(function(){return t.finishDestroy(e)}),this.destroyPromise)},i.finishDestroy=function(e){try{var t=function(){function t(){var t=oe(function(){return Promise.resolve(n.disconnectClientForDestroy(e)).then(function(){})},function(e,t){if(n.agentDestroyed=!0,n.agentDestroying=!1,n.setAgentState("destroyed"),e)throw t;return t});if(t&&t.then)return t.then(function(){})}var r=n.e2eClient,i=oe(function(){return Promise.resolve(null==r?void 0:r.disconnectAndWait(1e3,e)).then(function(){})},function(e,t){if(n.e2eClient===r&&(n.e2eClient=null),n.audioUplink.reset(),e)throw t;return t});return i&&i.then?i.then(t):t()},n=this;n.abortInitialization(new Error("Agent 初始化已取消")),n.cancelServiceMigration(),n.serviceReconnect=null,n.cancelReconnect(),n.cancelSessionRestart();var r=ie(function(){return Promise.resolve(n.stopASR()).then(function(){})},function(e){n.emitError("sdk","AGENT_ASR_STOP_FAILED","Agent 销毁时停止 ASR 失败",!1,e)});return Promise.resolve(r&&r.then?r.then(t):t())}catch(e){return Promise.reject(e)}},i.ask=function(e){try{var t=this;return t.assertRunning(),t.interactionPending=!0,t.llmPending=!0,t.llmProducedText=!1,t.suppressNextVoiceEnd=!1,t.emitConversation({state:"asking",text:e}),t.sendControl({type:"ask",message:{text:e}}),Promise.resolve()}catch(e){return Promise.reject(e)}},i.speak=function(t,n,r){var i;if(void 0===n&&(n=!0),void 0===r&&(r=!0),this.replaySending)return r&&(this.suppressNextVoiceEnd=!0),e.prototype.speak.call(this,t,n,r,arguments[3]);"draining"===(null==(i=this.serviceMigration)?void 0:i.phase)&&this.directSpeakOpen&&!n?this.assertE2EOpen():this.assertRunning(),this.interactionPending=!0,this.directSpeakOpen=!r,this.suppressNextVoiceEnd=!1,n&&this.emitConversation({state:"speaking-directly",text:t}),this.sendControl({type:"speak",message:{text:t,is_start:n,is_end:r}})},i.handleReplaySend=function(t){if(!this.serviceMigration){var n=this.replaySending;this.replaySending=!0;try{e.prototype.handleReplaySend.call(this,t)}finally{this.replaySending=n}}},i.speakByE2E=function(e){try{return this.speak(e),Promise.resolve()}catch(e){return Promise.reject(e)}},i.startASR=function(e){void 0===e&&(e={});try{var t=function(){var t;if(null==(t=n.microphone)||!t.isRecording){n.assertAudioChunkDuration();var r=e.inputStream?n.cloneASRInputStream(e.inputStream):void 0,i=++n.asrStartGeneration,o=!n.audioInputEnabled,s=new V({audio:n.agentOptions.audio,debugAudioChunks:n.agentOptions.debugAudioChunks,inputStream:r,usePcmWebCodecs:n.farendAudioEnabled,onFrame:function(e,t){var r,i;if(("running"===n.agentState||"draining"===(null==(r=n.serviceMigration)?void 0:r.phase))&&null!=(i=n.e2eClient)&&i.isOpen)try{var o;n.sendAudioFrame({data:e,timestamp:null!=t?t:Date.now()-((null==(o=n.agentOptions.audio)?void 0:o.chunkMs)||m.chunkMs)})}catch(e){n.stopASRAfterSocketClose()}},onError:function(e){return n.handleMicrophoneError(s,e)}});return n.microphone=s,ie(function(){return n.audioUplink.startInput(),o&&n.enableAudioInput(),n.emitConversation({state:"asking"}),n.assertASRStartActive(i),n.setASRState("requesting-permission"),n.assertASRStartActive(i),n.setASRState("starting"),n.assertASRStartActive(i),Promise.resolve(s.start()).then(function(){n.assertRunning(),n.farendAudioEnabled&&n.restartAudioPlaybackCapture(),n.setASRState("listening")})},function(e){return Promise.resolve(s.stop()).then(function(){var t,r,a="AUDIO_FIXED_TRACK_CANCELLED"===(null==e?void 0:e.agentCode),u=i===n.asrStartGeneration,c=!n.agentDestroyed&&!n.agentDestroying&&"running"===n.agentState&&Boolean(null==(t=n.e2eClient)?void 0:t.isOpen);if(n.microphone===s&&(n.microphone=null),u&&!a&&o&&null!=(r=n.e2eClient)&&r.isOpen)try{n.disableAudioInput()}catch(e){}throw!u||n.agentDestroyed||n.agentDestroying||(a&&c?n.setASRState("idle"):a||n.setASRState("failed")),a&&!c&&n.assertRunning(),e})})}},n=this;n.assertASRStartAllowed(),n.suppressNextVoiceEnd=!1;var r=function(){if(n.stopASRPromise)return Promise.resolve(n.stopASRPromise).then(function(){n.assertASRStartAllowed()})}();return Promise.resolve(r&&r.then?r.then(t):t())}catch(e){return Promise.reject(e)}},i.cloneASRInputStream=function(e){var t=e.getAudioTracks().find(function(e){return"ended"!==e.readyState});if(!t)throw new Error("ASR 输入流不包含有效音频轨道");return new MediaStream([t.clone()])},i.assertASRStartActive=function(e){if(e!==this.asrStartGeneration){var t=new Error("麦克风启动已取消");throw t.name="AbortError",t.agentCode="AUDIO_FIXED_TRACK_CANCELLED",t.retryable=!0,t}},i.stopASR=function(){var e=this;if(this.asrStartGeneration+=1,this.stopASRPromise)return this.stopASRPromise;var t,n=this.microphone;return null!=n&&n.isRecording?(this.microphone=null,this.stopASRPromise=this.finishStopASR(n).finally(function(){e.stopASRPromise=null}),this.stopASRPromise):(null!=(t=this.e2eClient)&&t.isOpen&&this.disableAudioInput(),Promise.resolve())},i.finishStopASR=function(e,t){void 0===t&&(t=!0);try{var n=this;return n.setASRState("stopping"),Promise.resolve(e.stop()).then(function(){return Promise.resolve(n.audioUplink.drain()).then(function(){t?(n.disableAudioInput(),n.setASRState("idle")):n.setASRState("failed")})})}catch(e){return Promise.reject(e)}},i.interrupt=function(){if(this.agentDestroyed||this.agentDestroying||this.serviceMigration&&"draining"!==this.serviceMigration.phase)return 0;this.sendControl({type:"interrupt"});var t=e.prototype.interrupt.call(this,"speak");return this.interactionPending=!1,this.llmPending=!1,this.llmProducedText=!1,this.directSpeakOpen=!1,this.pendingASR=!1,this.voicePlaying=!1,this.emitConversation({state:"interrupted"}),this.checkServiceMigration(),t},i.interruptConversation=function(e){void 0===e&&(e="user");try{return this.interrupt(),Promise.resolve()}catch(e){return Promise.reject(e)}},i.onSessionReloaded=function(e){try{var t,n=function(n){return t?n:("reconnecting"!==r.agentState&&(r.stateBeforeReconnect=r.readRestorableState(),r.setAgentState("reconnecting")),r.clearReconnectTimer(),r.sessionReloadFallback=!0,r.applySessionFeatures(e),Promise.resolve(r.replaceE2EConnection(e.e2e_resp)).then(function(){r.waitingForTtsaReload=!0,r.sessionReloadFallback=!1}))},r=this;if(r.agentDestroyed||r.agentDestroying)return Promise.resolve();r.cancelServiceMigration(),r.serviceReconnect=null,r.e2eSessionId=e.session_id;var i=function(){if(r.rejectInitialization)return r.applySessionFeatures(e),Promise.resolve(r.beginInitialSession(e)).then(function(){t=1})}();return Promise.resolve(i&&i.then?i.then(n):n(i))}catch(e){return Promise.reject(e)}},i.onSessionReloadExhausted=function(e){this.rejectInitialization?this.abortInitialization(e instanceof Error?e:new Error("Agent 初始化期间 TTSA Session 恢复失败")):"reconnecting"===this.agentState&&this.failReconnect(e)},i.replaceE2EConnection=function(e,t){void 0===t&&(t=!0);try{var n=this,r=n.resolveE2EConnection(e),i=r.wsUrl,o=r.token;n.currentE2EUrl=i;var s,a=n.e2eClient;n.audioUplink.reset(),s=new f({wsUrl:i,token:o,audioInputEnabled:n.audioInputEnabled,WebSocketCtor:n.agentOptions.webSocketCtor,onStateChange:function(e){n.e2eClient===s&&("open"===e&&n.audioUplink.reset(Date.now()),n.safeEmit(function(){var t;return null==(t=n.agentOptions.callbacks)||null==t.onSocketStateChange?void 0:t.onSocketStateChange(e)}))},onEvent:function(e){var t,r;n.e2eClient===s&&"closing"!==(null==(t=n.serviceMigration)?void 0:t.phase)&&"failed"!==(null==(r=n.serviceMigration)?void 0:r.phase)&&n.handleServerEvent(e)},onError:function(e){n.e2eClient===s&&"initializing"!==n.agentState&&"reconnecting"!==n.agentState&&n.emitError("network","E2E_SOCKET_ERROR",e.message,!0,e)},onClose:function(e){n.e2eClient===s&&n.handleSocketClose(e)}}),n.e2eClient=s,null==a||a.disconnect(1e3,"e2e_connection_replaced");var u=function(){if(t)return Promise.resolve(s.connect()).then(function(){})}();return Promise.resolve(u&&u.then?u.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},i.resolveE2EConnection=function(e){var t=Boolean(null==e?void 0:e.ws_url),n=Boolean(null==e?void 0:e.e2e_token);if(t!==n)throw new Error("统一 session 响应的 e2e_resp 必须同时返回 ws_url 和 e2e_token");if(t&&n)return{wsUrl:null==e?void 0:e.ws_url,token:null==e?void 0:e.e2e_token};var r=Boolean(this.agentOptions.e2eServer);if(r!==Boolean(this.agentOptions.authToken))throw new Error("e2eServer 和 authToken 必须同时配置");if(!r)throw new Error("统一 session 响应未返回 e2e_resp.ws_url,且未配置 e2eServer");return{wsUrl:this.agentOptions.e2eServer,token:this.agentOptions.authToken}},i.sendControl=function(e){try{var t;null==(t=this.e2eClient)||t.send(e)}catch(e){throw this.emitError("network","E2E_SEND_FAILED","E2E WebSocket 发送失败",!0,e),e}},i.assertAudioChunkDuration=function(){var e,t=(null==(e=this.agentOptions.audio)?void 0:e.chunkMs)||m.chunkMs;if(this.farendAudioEnabled&&t!==m.chunkMs){var n=new Error("AU v1 音频分片固定为 100ms");throw n.name="NotSupportedError",n.agentCode="AUDIO_CHUNK_DURATION_UNSUPPORTED",n.retryable=!1,this.emitError("sdk",n.agentCode,n.message,n.retryable,n),n}},i.sendAudioFrame=function(e){if(this.farendAudioEnabled)this.agentOptions.debugAudioChunks&&_("[Agent][E2E] nearend AU chunk",e.data,{timestamp:e.timestamp,stream_id:1}),this.audioUplink.offerNearend(e);else{this.agentOptions.debugAudioChunks&&_("[Agent][E2E] nearend raw WebM/Opus chunk",e.data,{timestamp:e.timestamp});try{var t;null==(t=this.e2eClient)||t.sendBinary(e.data)}catch(e){this.handleAudioUplinkError(e instanceof Error?e:new Error("E2E nearend 音频帧发送失败"))}}},i.handleAudioUplinkError=function(e){var t=this;this.emitError("network","E2E_AUDIO_SEND_FAILED",this.farendAudioEnabled?"E2E AU 音频帧发送失败":"E2E 音频帧发送失败",!0,e);var n=this.microphone;if(null!=n&&n.isRecording&&!this.stopASRPromise){this.setASRState("failed"),this.microphone=null;var r=this.finishFailedASR(n).finally(function(){t.stopASRPromise===r&&(t.stopASRPromise=null)});this.stopASRPromise=r}},i.applySessionFeatures=function(e){var t,n,r,i,o,s,a,u,c,l=null!=(t=null==(n=e.e2e_resp)||null==(n=n.features)?void 0:n.auto_send_asr_to_llm)?t:null==(r=e.features)?void 0:r.auto_send_asr_to_llm;"boolean"==typeof l&&(this.autoSendASRToLLM=l);var h=null!=(i=null==(o=e.e2e_resp)||null==(o=o.features)||null==(o=o.speech_frontend)?void 0:o.enable_aec)?i:null==(s=e.features)||null==(s=s.speech_frontend)?void 0:s.enable_aec;if(this.farendAudioEnabled="boolean"==typeof h?h:null!=(a=null!=(u=this.agentOptions.requestedEnableAec)?u:null==(c=this.agentOptions.audio)?void 0:c.echoCancellationEnabled)&&a,this.farendAudioEnabled||this.audioUplink.clearFarend(),this.farendAudioEnabled||this.originalOnAudioPlaybackData)return this.setAudioPlaybackDataHandler(this.playbackDataHandler),void(this.farendAudioEnabled&&this.enableAudioPlaybackCapture());this.setAudioPlaybackDataHandler(void 0)},i.forwardFarendAudio=function(e){var t,n,r,i=Boolean(null==(t=this.microphone)?void 0:t.isRecording),o=Boolean(null==(n=this.e2eClient)?void 0:n.isOpen);this.farendAudioEnabled&&i&&o?(this.agentOptions.debugAudioChunks&&_("[Agent][E2E] farend AU chunk",e.data,{timestamp:e.timestamp,stream_id:2,codec:e.codec,sampleRate:e.sampleRate,channels:1,samples:e.samples,speech_id:e.speech_id,isFirstChunk:e.isFirstChunk}),this.audioUplink.offerFarend({data:e.data,timestamp:e.timestamp,isFirstChunk:e.isFirstChunk})):null==(r=globalThis.avatarSDKLogger)||null==r.log||r.log("[Agent][AudioUplink]","farend.drop",{reason:this.farendAudioEnabled?i?"e2e_not_open":"microphone_not_recording":"aec_disabled",timestamp:e.timestamp,isFirstChunk:e.isFirstChunk})},i.handleMicrophoneError=function(e,t){var n,r=this,i=t,o="MediaRecorderError"===t.name,s="AudioEncoderError"===t.name,a=o||s,u="NotSupportedError"===t.name,c=Boolean(i.agentCode);if(a&&this.microphone===e&&"stopping"!==this.asrState){this.microphone=null;var l=this.finishFailedASR(e).finally(function(){r.stopASRPromise===l&&(r.stopASRPromise=null)});this.stopASRPromise=l}this.emitError(a?"asr":c||u?"sdk":"permission",i.agentCode||(o?"MEDIA_RECORDER_ERROR":s?"AUDIO_ENCODER_ERROR":"MICROPHONE_ERROR"),t.message,null!=(n=i.retryable)?n:!u,t)},i.finishFailedASR=function(e){try{var t=function(){try{n.disableAudioInput()}catch(e){}},n=this,r=ie(function(){return Promise.resolve(e.stop()).then(function(){return Promise.resolve(n.audioUplink.drain()).then(function(){})})},function(e){n.emitError("sdk","MICROPHONE_CLEANUP_FAILED","麦克风异常后的资源清理失败",!1,e)});return Promise.resolve(r&&r.then?r.then(t):t())}catch(e){return Promise.reject(e)}},i.enableAudioInput=function(){var e;this.audioInputEnabled||(this.sendControl({type:"event",message:"audio_input_on"}),this.audioInputEnabled=!0,null==(e=this.e2eClient)||e.setAudioInputEnabled(!0))},i.disableAudioInput=function(){var e;this.audioInputEnabled&&(this.sendControl({type:"event",message:"audio_input_off"}),this.audioInputEnabled=!1,null==(e=this.e2eClient)||e.setAudioInputEnabled(!1))},i.handleServerEvent=function(e){var t;if(!this.agentDestroyed&&!this.agentDestroying)switch(e.type){case"service_update":return void this.handleServiceUpdate(e);case"pong":default:return;case"asr_result":return void this.handleASRResult(e);case"llm_response":return void this.handleLLMResponse(e);case"semantic_judge_round_result":return void this.handleSemanticJudgeResult(e);case"volume_and_repetition_text_response":return void(!0===(null==(t=e.message)?void 0:t.skip)&&(this.pendingASR=!1,this.checkServiceMigration()));case"error":return void this.handleBackendError(e)}},i.handleASRResult=function(e){var t=this;this.autoSendASRToLLM&&(this.pendingASR="string"==typeof e.text&&Boolean(e.text.trim()));var n={text:"string"==typeof e.text?e.text:"",isFinal:!0===e.is_final,raw:e};this.safeEmit(function(){var e;return null==(e=t.agentOptions.callbacks)||null==e.onASRResult?void 0:e.onASRResult(n)}),this.checkServiceMigration()},i.handleLLMResponse=function(e){var t=this;if("chunk"===e.event||"done"===e.event){this.llmPending="done"!==e.event,this.pendingASR=!1,"chunk"===e.event&&e.text&&(this.interactionPending=!0,this.llmProducedText=!0),"done"===e.event&&(this.llmProducedText||(this.interactionPending=!1),this.llmProducedText=!1);var n=e.usage,r=o({event:e.event},"string"==typeof e.text?{text:e.text}:{},!0===e.is_first?{isFirst:!0}:{},n?{usage:{promptTokens:this.readFiniteNumber(n.prompt_tokens),completionTokens:this.readFiniteNumber(n.completion_tokens),totalTokens:this.readFiniteNumber(n.total_tokens),cachedTokens:this.readFiniteNumber(n.cached_tokens)}}:{},{raw:e});this.safeEmit(function(){var e;return null==(e=t.agentOptions.callbacks)||null==e.onLLMResponse?void 0:e.onLLMResponse(r)}),this.checkServiceMigration()}},i.handleSemanticJudgeResult=function(e){var t=this;if(e.message&&"object"==typeof e.message){var n=e.message,r={query:"string"==typeof n.query?n.query:"",meaningful:!0===n.meaningful,action:"string"==typeof n.action?n.action:"",raw:e};this.safeEmit(function(){var e;return null==(e=t.agentOptions.callbacks)||null==e.onSemanticJudgeResult?void 0:e.onSemanticJudgeResult(r)}),!1===n.meaningful&&(this.pendingASR=!1,this.checkServiceMigration())}},i.forwardVoiceEnd=function(){var e,t;if(this.suppressNextVoiceEnd)return this.suppressNextVoiceEnd=!1,this.interactionPending=!1,void this.checkServiceMigration();if(!(this.agentDestroyed||this.agentDestroying||"running"!==this.agentState&&"draining"!==(null==(e=this.serviceMigration)?void 0:e.phase)||null==(t=this.e2eClient))&&t.isOpen)try{this.sendControl({type:"event",message:"voice_end"}),this.interactionPending=!1,this.checkServiceMigration()}catch(e){}},i.readFiniteNumber=function(e){return"number"==typeof e&&Number.isFinite(e)?e:0},i.handleBackendError=function(e){var t,n=["permission","network","asr","brain","ttsa","quota","sdk"].includes(e.domain)?e.domain:"sdk",r=String(null!=(t=e.code)?t:"BACKEND_ERROR"),i="string"==typeof e.message?e.message:"E2E 后端错误";"asr"===n&&(this.stopASRAfterSocketClose(),this.pendingASR=!1),"brain"===n&&(this.pendingASR=!1,this.llmPending=!1,this.llmProducedText||(this.interactionPending=!1)),this.emitConversation({state:"failed"}),this.emitError(n,r,i,"quota"!==n,e),this.checkServiceMigration()},i.handleServiceUpdate=function(e){var t;if(!this.serviceMigration||"connecting"===this.serviceMigration.phase&&null!=(t=this.e2eClient)&&t.isOpen){var n=null,r=e.grace_period_ms;try{var i=e.reconnect;if(!i||"string"!=typeof i.ws_url||"string"!=typeof i.e2e_token||!i.e2e_token||i.session_id!==this.e2eSessionId||"number"!=typeof r||!Number.isSafeInteger(r)||r<0||r>se||"number"!=typeof i.expires_in_ms||!Number.isSafeInteger(i.expires_in_ms)||i.expires_in_ms<=0||i.expires_in_ms>se)throw new Error("Invalid migration payload");var o=new URL(i.ws_url);if(!["ws:","wss:"].includes(o.protocol)||o.username||o.password||o.hash||this.currentE2EUrl.startsWith("wss:")&&"wss:"!==o.protocol||1!==o.searchParams.getAll("session_id").length||o.searchParams.get("session_id")!==this.e2eSessionId||1!==o.searchParams.getAll("token").length||o.searchParams.get("token")!==i.e2e_token)throw new Error("Invalid migration URL");n={session_id:this.e2eSessionId,ws_url:i.ws_url,e2e_token:i.e2e_token,expiresAt:Date.now()+i.expires_in_ms,attempts:0}}catch(e){return void(this.serviceMigration?this.failServiceMigration("E2E_SERVICE_UPDATE_INVALID","服务更新缺少有效的同房重连凭据"):this.startServiceMigration(null,0))}this.serviceMigration&&(this.stateBeforeReconnect=this.serviceMigration.previousState,this.cancelServiceMigration()),this.serviceReconnect=n,this.startServiceMigration(n,r)}},i.startServiceMigration=function(e,t){var n,r=this;if(!(this.serviceMigration||this.agentDestroyed||this.agentDestroying)){var i="reconnecting"===this.agentState?this.stateBeforeReconnect:this.agentState;this.cancelReconnect();var o=function(){},s=function(e){},a=new Promise(function(e,t){o=e,s=t});a.catch(function(){});var u={reconnect:e,previousState:i,phase:"draining",departAt:Date.now()+Math.max(0,t-3e3),quietUntil:0,audioStopped:!1,timer:null,expiryTimer:null,completion:a,resolve:o,reject:s};if(this.serviceMigration=u,this.stateBeforeReconnect=this.readRestorableState(),e){if(u.expiryTimer=setTimeout(function(){r.failServiceMigration("E2E_MIGRATION_TOKEN_EXPIRED","E2E 迁移凭据已过期,请结束会话后重新初始化")},Math.max(0,e.expiresAt-Date.now())),this.setMigrationState("reconnecting"),this.serviceMigration===u&&!this.agentDestroying){var c=Boolean((null==(n=this.microphone)?void 0:n.isRecording)||this.stopASRPromise||this.audioInputEnabled);u.timer=setTimeout(function(){r.closeForServiceMigration(u)},Math.max(0,u.departAt-Date.now())),this.stopASR().then(function(){r.serviceMigration===u&&"draining"===u.phase&&(u.audioStopped=!0,u.quietUntil=Date.now()+(c?2e3:0),r.checkServiceMigration())}).catch(function(){r.serviceMigration===u&&r.failServiceMigration("E2E_MIGRATION_AUDIO_STOP_FAILED","E2E 迁移时停止音频失败")})}}else this.failServiceMigration("E2E_SERVICE_UPDATE_INVALID","服务更新缺少有效的同房重连凭据")}},i.checkServiceMigration=function(){var e=this,t=this.serviceMigration;if(t&&"draining"===t.phase&&t.audioStopped){var n=t.quietUntil-Date.now();Date.now()>=t.departAt||n<=0&&!this.interactionPending&&!this.llmPending&&!this.directSpeakOpen&&!this.pendingASR&&!this.voicePlaying?this.closeForServiceMigration(t):n>0?(null!==t.timer&&clearTimeout(t.timer),t.timer=setTimeout(function(){return e.checkServiceMigration()},Math.max(0,Math.min(n,t.departAt-Date.now())))):(null!==t.timer&&clearTimeout(t.timer),t.timer=setTimeout(function(){e.closeForServiceMigration(t)},Math.max(0,t.departAt-Date.now())))}},i.closeForServiceMigration=function(e){try{var t=this;if(t.serviceMigration!==e||"draining"!==e.phase||t.agentDestroying||t.agentDestroyed)return Promise.resolve();e.phase="closing",null!==e.timer&&clearTimeout(e.timer),e.timer=null,t.audioUplink.reset(),t.audioInputEnabled=!1;var n=t.e2eClient;return Promise.resolve(null==n?void 0:n.disconnectAndWait(1e3,"service_update",3e3)).then(function(r){var i;function o(n){var r;if(i)return n;t.serviceMigration!==e||t.agentDestroying||t.agentDestroyed||(e.phase="connecting",t.interactionPending=!1,t.llmPending=!1,t.llmProducedText=!1,t.directSpeakOpen=!1,t.pendingASR=!1,t.voicePlaying=!1,t.scheduleServiceReconnect(e,0===(null==(r=e.reconnect)?void 0:r.attempts)))}if(t.serviceMigration===e&&"closing"===e.phase&&!t.agentDestroying&&!t.agentDestroyed){if(!1!==r){t.e2eClient===n&&(t.e2eClient=null);var s=ie(function(){return Promise.resolve(t.replaceE2EConnection(e.reconnect,!1)).then(function(){})},function(){t.serviceMigration===e&&t.failServiceMigration("E2E_MIGRATION_FAILED","创建迁移连接失败"),i=1});return s&&s.then?s.then(o):o(s)}t.failServiceMigration("E2E_MIGRATION_CLOSE_TIMEOUT","旧 E2E 未确认关闭,已停止迁移以避免双连接")}})}catch(e){return Promise.reject(e)}},i.scheduleServiceReconnect=function(e,t){var n,r,i=this;if(void 0===t&&(t=!1),!(this.serviceMigration!==e||"connecting"!==e.phase||this.agentDestroying||this.agentDestroyed||this.reconnectInFlight)){null!==e.timer&&clearTimeout(e.timer);var o=t?0:Math.max(100,this.getReconnectDelay((null!=(n=null==(r=e.reconnect)?void 0:r.attempts)?n:1)-1));e.timer=setTimeout(function(){i.attemptServiceReconnect(e)},o)}},i.attemptServiceReconnect=function(e){try{var t=this;if(t.serviceMigration!==e||"connecting"!==e.phase||t.agentDestroying||t.agentDestroyed)return Promise.resolve();e.timer=null;var n=t.e2eClient;if(!n||!e.reconnect)return Promise.resolve();if(Date.now()>=e.reconnect.expiresAt)return t.failServiceMigration("E2E_MIGRATION_TOKEN_EXPIRED","E2E 迁移凭据已过期,请结束会话后重新初始化"),Promise.resolve();t.reconnectInFlight=!0,e.reconnect.attempts+=1;var r=setTimeout(function(){return n.disconnect(1e3,"migration_connect_timeout")},1e4);return Promise.resolve(oe(function(){return ie(function(){return Promise.resolve(n.connect()).then(function(){if(clearTimeout(r),t.serviceMigration===e&&n.isOpen&&!t.agentDestroying&&!t.agentDestroyed)return Promise.resolve(t.stopASRPromise).then(function(){if(t.serviceMigration===e&&n.isOpen&&!t.agentDestroying&&!t.agentDestroyed){try{t.setASRState("idle")}catch(e){}if(t.serviceMigration===e&&!t.agentDestroyed&&!t.agentDestroying){var r=e.previousState;t.cancelServiceMigration(),t.setMigrationState(r)}}})})},function(){})},function(n,i){if(clearTimeout(r),t.serviceMigration===e&&(t.reconnectInFlight=!1,t.scheduleServiceReconnect(e)),n)throw i;return i}))}catch(e){return Promise.reject(e)}},i.failServiceMigration=function(e,t){var n,r=this.serviceMigration;r&&"failed"!==r.phase&&(r.phase="failed",null!==r.timer&&clearTimeout(r.timer),null!==r.expiryTimer&&clearTimeout(r.expiryTimer),r.timer=null,r.expiryTimer=null,this.cancelReconnect(),this.stopASRAfterSocketClose(),null==(n=this.e2eClient)||n.disconnect(1e3,"migration_failed"),r.reject(new Error(t)),this.abortInitialization(new Error(t)),this.setMigrationState("failed"),this.emitError("E2E_CLOSE_4009"===e?"quota":"network",e,t,!1))},i.setMigrationState=function(e){try{this.setAgentState(e)}catch(e){}},i.cancelServiceMigration=function(){var e=this.serviceMigration;e&&(this.serviceMigration=null,null!==e.timer&&clearTimeout(e.timer),null!==e.expiryTimer&&clearTimeout(e.expiryTimer),this.reconnectInFlight=!1,e.resolve())},i.handleSocketClose=function(e){if(!this.agentDestroyed&&!this.agentDestroying)if(this.serviceMigration){var t=this.serviceMigration;"draining"===t.phase?4011===e.code||ce.has(e.code)?this.closeForServiceMigration(t):this.failServiceMigration("E2E_CLOSE_"+e.code,"E2E 更新迁移被服务端终止"):"connecting"===t.phase&&(4011===e.code||ce.has(e.code)?this.scheduleServiceReconnect(t):this.failServiceMigration("E2E_CLOSE_"+e.code,"E2E 更新迁移被服务端终止"))}else if(4011!==e.code)if(this.rejectInitialization)this.abortInitialization(new Error(("Agent 初始化期间 E2E WebSocket 已关闭: "+e.code+" "+(e.reason||"")).trim()));else if(this.audioUplink.reset(),this.stopASRAfterSocketClose(),this.shouldReconnect(e))this.beginReconnect(e);else{this.setAgentState("failed");var n=4009===e.code?"quota":"network";this.emitError(n,"E2E_CLOSE_"+e.code,e.reason||ue[e.code]||"E2E WebSocket 已关闭","quota"!==n,{code:e.code,reason:e.reason,wasClean:e.wasClean})}else this.startServiceMigration(this.serviceReconnect,0)},i.shouldReconnect=function(e){return this.reconnectOptions.enabled&&"idle"!==this.agentState&&"initializing"!==this.agentState&&"destroyed"!==this.agentState&&ce.has(e.code)},i.beginReconnect=function(e){var t;"reconnecting"!==this.agentState&&(this.stateBeforeReconnect=this.readRestorableState(),this.reconnectAttempt=0,this.sessionReloadFallback=!1,this.setAgentState("reconnecting"),null==globalThis.addEventListener||globalThis.addEventListener("online",this.handleOnlineForReconnect),this.emitError("network","E2E_RECONNECTING","E2E WebSocket 已断开,正在重连",!0,{code:e.code,reason:e.reason,wasClean:e.wasClean})),this.audioInputEnabled=!1,null==(t=this.e2eClient)||t.setAudioInputEnabled(!1),this.scheduleE2EReconnect(!1)},i.scheduleE2EReconnect=function(e){var t=this;if(!(this.agentDestroyed||this.agentDestroying||this.serviceMigration||"reconnecting"!==this.agentState||null!==this.reconnectTimer||this.reconnectInFlight||this.sessionReloadFallback))if(this.reconnectAttempt>=this.reconnectOptions.maxAttempts)this.fallbackToSessionReload();else{var n=e?0:this.getReconnectDelay(this.reconnectAttempt);this.reconnectTimer=globalThis.setTimeout(function(){t.reconnectTimer=null,t.attemptE2EReconnect()},n)}},i.attemptE2EReconnect=function(){try{var e=this,t=e.e2eClient;if(!t||e.serviceMigration||e.agentDestroyed||e.agentDestroying||"reconnecting"!==e.agentState)return Promise.resolve();e.reconnectInFlight=!0,e.reconnectAttempt+=1;var n=oe(function(){return ie(function(){return Promise.resolve(t.connect()).then(function(){e.e2eClient!==t||e.serviceMigration||e.agentDestroyed||e.agentDestroying||e.waitingForTtsaReload||e.finishReconnect()})},function(){e.e2eClient!==t||e.serviceMigration||e.agentDestroyed||e.agentDestroying||e.scheduleE2EReconnect(!1)})},function(n,r){if(e.e2eClient!==t||e.serviceMigration||(e.reconnectInFlight=!1),e.e2eClient!==t||e.serviceMigration||"reconnecting"!==e.agentState||null!==e.reconnectTimer||e.sessionReloadFallback||e.scheduleE2EReconnect(!1),n)throw r;return r});return Promise.resolve(n&&n.then?n.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},i.fallbackToSessionReload=function(){try{var e=this;if(e.serviceMigration||e.sessionReloadFallback||e.agentDestroyed||e.agentDestroying)return Promise.resolve();e.sessionReloadFallback=!0,e.clearReconnectTimer();var t=ie(function(){return Promise.resolve(e.restartSessionForTransport("e2e_reconnect_exhausted")).then(function(){})},function(t){e.failReconnect(t)});return Promise.resolve(t&&t.then?t.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},i.finishReconnect=function(){var e=this.stateBeforeReconnect;this.cancelReconnect(),"idle"!==this.asrState&&this.setASRState("idle"),this.setAgentState(e)},i.failReconnect=function(e){this.cancelReconnect(),this.setAgentState("failed"),this.emitConversation({state:"failed"}),this.emitError("network","E2E_RECONNECT_EXHAUSTED","E2E WebSocket 重连失败,请重新初始化 Agent",!1,e)},i.cancelReconnect=function(){this.clearReconnectTimer(),null==globalThis.removeEventListener||globalThis.removeEventListener("online",this.handleOnlineForReconnect),this.reconnectAttempt=0,this.reconnectInFlight=!1,this.sessionReloadFallback=!1,this.waitingForTtsaReload=!1},i.clearReconnectTimer=function(){null!==this.reconnectTimer&&(globalThis.clearTimeout(this.reconnectTimer),this.reconnectTimer=null)},i.getReconnectDelay=function(e){if(0===this.reconnectOptions.initialDelayMs)return 0;var t=Math.min(this.reconnectOptions.maxDelayMs,this.reconnectOptions.initialDelayMs*Math.pow(2,e));return 0===t?0:Math.round(t*(.8+.4*Math.random()))},i.readRestorableState=function(){return"running"===this.agentState||"stopped"===this.agentState||"ready"===this.agentState?this.agentState:"ready"},i.normalizeReconnectOptions=function(e){var t,n=this.readNonNegativeNumber(null==e?void 0:e.initialDelayMs,500);return{enabled:null==(t=null==e?void 0:e.enabled)||t,maxAttempts:Math.max(1,Math.floor(this.readNonNegativeNumber(null==e?void 0:e.maxAttempts,6))),initialDelayMs:n,maxDelayMs:Math.max(n,this.readNonNegativeNumber(null==e?void 0:e.maxDelayMs,8e3))}},i.readNonNegativeNumber=function(e,t){return"number"==typeof e&&Number.isFinite(e)&&e>=0?e:t},i.stopASRAfterSocketClose=function(){var e=this;if(this.asrStartGeneration+=1,!this.stopASRPromise){var t=this.microphone;null!=t&&t.isRecording&&(this.microphone=null,this.stopASRPromise=this.finishStopASR(t,!1).catch(function(t){e.emitError("sdk","MICROPHONE_CLEANUP_FAILED","WebSocket 断开后清理麦克风失败",!1,t)}).finally(function(){e.stopASRPromise=null}))}},i.setAgentState=function(e){var t;this.agentState=e,this.agentDestroyed&&"destroyed"!==e||null==(t=this.agentOptions.callbacks)||null==t.onAgentStateChange||t.onAgentStateChange(e)},i.setASRState=function(e){var t=this;this.asrState=e,this.safeEmit(function(){var n;return null==(n=t.agentOptions.callbacks)||null==n.onASRStateChange?void 0:n.onASRStateChange(e)})},i.emitConversation=function(e){var t=this;this.safeEmit(function(){var n;return null==(n=t.agentOptions.callbacks)||null==n.onConversationChange?void 0:n.onConversationChange(e)})},i.emitError=function(e,t,n,r,i){var o=this,s={domain:e,code:t,message:n,retryable:r,cause:i};"asr"===e&&this.setASRState("failed"),this.safeEmit(function(){var e;return null==(e=o.agentOptions.callbacks)||null==e.onError?void 0:e.onError(s)})},i.safeEmit=function(e){this.agentDestroyed||this.agentDestroying||e()},i.assertRunning=function(){if(this.assertE2EOpen(),this.serviceMigration)throw new Error("Agent 正在迁移 E2E,请等待恢复后再开始新交互");if("running"!==this.agentState)throw new Error("Agent 尚未启动,请先调用 start()")},i.assertASRStartAllowed=function(){if(this.assertRunning(),this.getStatus()===c.invisible)throw new Error("数字人处于隐身状态,无法启动 ASR,请先退出隐身模式")},i.assertE2EOpen=function(){var e;if(this.assertNotDestroyed(),null==(e=this.e2eClient)||!e.isOpen)throw new Error("Agent 尚未连接 E2E WebSocket")},i.assertNotDestroyed=function(){if(this.agentDestroyed||this.agentDestroying)throw new Error("Agent 已销毁")},t}(e);export{de as default};