ttp-agent-sdk 2.48.2 → 2.48.5

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.
@@ -12047,7 +12047,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
12047
12047
 
12048
12048
  // SDK build time for debugging
12049
12049
  if (true) {
12050
- helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
12050
+ helloMessage.lastBuildTime = "2026-08-20T16:29:04.205Z";
12051
12051
  }
12052
12052
  try {
12053
12053
  this.ws.send(JSON.stringify(helloMessage));
@@ -21357,8 +21357,8 @@ var VoiceSDK = _v2_VoiceSDK_js__WEBPACK_IMPORTED_MODULE_0__["default"];
21357
21357
 
21358
21358
 
21359
21359
  // Version - injected at build time from package.json via webpack DefinePlugin
21360
- var VERSION = "2.48.2";
21361
- var BUILD_TIME = "2026-08-20T14:41:57.957Z";
21360
+ var VERSION = "2.48.5";
21361
+ var BUILD_TIME = "2026-08-20T16:29:04.205Z";
21362
21362
  console.log("%c TTP Agent SDK v".concat(VERSION, " (").concat(BUILD_TIME, ") "), 'background: #4f46e5; color: white; font-size: 12px; font-weight: bold; padding: 2px 6px; border-radius: 4px;');
21363
21363
 
21364
21364
  // Named exports
@@ -25620,6 +25620,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25620
25620
  _this._mediaStreamDest = null;
25621
25621
  _this._htmlAudioRouteActive = false;
25622
25622
  _this._htmlAudioPlayOk = false;
25623
+ // Greeting (and other bursts) fire many playChunk()s without await.
25624
+ // Serialize context creation so they cannot open two AudioContexts
25625
+ // at different rates in the middle of a sentence.
25626
+ _this._audioContextInitPromise = null;
25623
25627
 
25624
25628
  // Track temporary listener in waitForAudioContextReady() for cleanup
25625
25629
  _this._waitForReadyStateHandler = null;
@@ -27179,9 +27183,35 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27179
27183
  value: (function () {
27180
27184
  var _initializeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
27181
27185
  var _this8 = this;
27182
- var ttsSampleRate, useHardwareRate, desiredSampleRate, contextFits, canReuseShared, setupAfterResume, ctxOpts, _t4;
27183
27186
  return _regenerator().w(function (_context8) {
27184
- while (1) switch (_context8.p = _context8.n) {
27187
+ while (1) switch (_context8.n) {
27188
+ case 0:
27189
+ if (!this._audioContextInitPromise) {
27190
+ _context8.n = 1;
27191
+ break;
27192
+ }
27193
+ return _context8.a(2, this._audioContextInitPromise);
27194
+ case 1:
27195
+ this._audioContextInitPromise = this._initializeAudioContextImpl().finally(function () {
27196
+ _this8._audioContextInitPromise = null;
27197
+ });
27198
+ return _context8.a(2, this._audioContextInitPromise);
27199
+ }
27200
+ }, _callee7, this);
27201
+ }));
27202
+ function initializeAudioContext() {
27203
+ return _initializeAudioContext.apply(this, arguments);
27204
+ }
27205
+ return initializeAudioContext;
27206
+ }())
27207
+ }, {
27208
+ key: "_initializeAudioContextImpl",
27209
+ value: function () {
27210
+ var _initializeAudioContextImpl2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
27211
+ var _this9 = this;
27212
+ var ttsSampleRate, useHardwareRate, desiredSampleRate, contextFits, canReuseShared, setupAfterResume, ctxOpts, _t4;
27213
+ return _regenerator().w(function (_context9) {
27214
+ while (1) switch (_context9.p = _context9.n) {
27185
27215
  case 0:
27186
27216
  ttsSampleRate = this._ttsSampleRate();
27187
27217
  useHardwareRate = this._htmlHopNeedsHardwareRate(); // Destination path: match TTS (24 kHz). HTML last-hop: omit so the
@@ -27196,27 +27226,27 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27196
27226
  _sharedPlayerSampleRate = null;
27197
27227
  }
27198
27228
  contextFits = function contextFits(rate) {
27199
- if (useHardwareRate) return _this8._isHardwarePlaybackRate(rate);
27229
+ if (useHardwareRate) return _this9._isHardwarePlaybackRate(rate);
27200
27230
  return Math.abs(rate - desiredSampleRate) <= 100;
27201
27231
  }; // Check if current instance AudioContext exists and matches
27202
27232
  if (!this.audioContext) {
27203
- _context8.n = 3;
27233
+ _context9.n = 3;
27204
27234
  break;
27205
27235
  }
27206
27236
  if (!(this.audioContext.state === 'closed')) {
27207
- _context8.n = 1;
27237
+ _context9.n = 1;
27208
27238
  break;
27209
27239
  }
27210
27240
  this._invalidateClosedAudioContext();
27211
- _context8.n = 3;
27241
+ _context9.n = 3;
27212
27242
  break;
27213
27243
  case 1:
27214
27244
  if (!contextFits(this.audioContext.sampleRate)) {
27215
- _context8.n = 2;
27245
+ _context9.n = 2;
27216
27246
  break;
27217
27247
  }
27218
27248
  this._ensureHtmlAudioPlaying();
27219
- return _context8.a(2);
27249
+ return _context9.a(2);
27220
27250
  case 2:
27221
27251
  console.warn("\u26A0\uFE0F AudioPlayer: AudioContext sample rate (".concat(this.audioContext.sampleRate, "Hz) doesn't match playback hop, recreating..."));
27222
27252
  this.stopImmediate();
@@ -27227,44 +27257,44 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27227
27257
  // causing newly created AudioContexts to fail silently.
27228
27258
  canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && contextFits(_sharedPlayerContext.sampleRate);
27229
27259
  if (!canReuseShared) {
27230
- _context8.n = 8;
27260
+ _context9.n = 8;
27231
27261
  break;
27232
27262
  }
27233
27263
  console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(_sharedPlayerContext.sampleRate, "Hz (iOS-safe)"));
27234
27264
  this.audioContext = _sharedPlayerContext;
27235
27265
  setupAfterResume = function setupAfterResume() {
27236
- _this8.setupAudioContextStateMonitoring();
27237
- if (_this8.gainNode) {
27266
+ _this9.setupAudioContextStateMonitoring();
27267
+ if (_this9.gainNode) {
27238
27268
  try {
27239
- _this8.gainNode.disconnect();
27269
+ _this9.gainNode.disconnect();
27240
27270
  } catch (e) {
27241
27271
  console.warn('⚠️ AudioPlayer: Error disconnecting old GainNode:', e);
27242
27272
  }
27243
27273
  }
27244
- _this8.gainNode = _this8.audioContext.createGain();
27245
- _this8.gainNode.gain.value = 1.0;
27246
- _this8._connectGainToOutput();
27247
- if (!_this8._audioContextPrimed) {
27248
- _this8._primeAudioContext();
27274
+ _this9.gainNode = _this9.audioContext.createGain();
27275
+ _this9.gainNode.gain.value = 1.0;
27276
+ _this9._connectGainToOutput();
27277
+ if (!_this9._audioContextPrimed) {
27278
+ _this9._primeAudioContext();
27249
27279
  }
27250
27280
  };
27251
27281
  if (!(this.audioContext.state === 'suspended')) {
27252
- _context8.n = 7;
27282
+ _context9.n = 7;
27253
27283
  break;
27254
27284
  }
27255
- _context8.p = 4;
27256
- _context8.n = 5;
27285
+ _context9.p = 4;
27286
+ _context9.n = 5;
27257
27287
  return this.audioContext.resume();
27258
27288
  case 5:
27259
- _context8.n = 7;
27289
+ _context9.n = 7;
27260
27290
  break;
27261
27291
  case 6:
27262
- _context8.p = 6;
27263
- _t4 = _context8.v;
27292
+ _context9.p = 6;
27293
+ _t4 = _context9.v;
27264
27294
  console.warn('⚠️ AudioPlayer: Error resuming shared context:', _t4);
27265
27295
  case 7:
27266
27296
  setupAfterResume();
27267
- return _context8.a(2);
27297
+ return _context9.a(2);
27268
27298
  case 8:
27269
27299
  console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate || 'hardware default', ")"));
27270
27300
 
@@ -27315,34 +27345,33 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27315
27345
  this._primeAudioContext();
27316
27346
  }
27317
27347
  case 9:
27318
- return _context8.a(2);
27348
+ return _context9.a(2);
27319
27349
  }
27320
- }, _callee7, this, [[4, 6]]);
27350
+ }, _callee8, this, [[4, 6]]);
27321
27351
  }));
27322
- function initializeAudioContext() {
27323
- return _initializeAudioContext.apply(this, arguments);
27352
+ function _initializeAudioContextImpl() {
27353
+ return _initializeAudioContextImpl2.apply(this, arguments);
27324
27354
  }
27325
- return initializeAudioContext;
27355
+ return _initializeAudioContextImpl;
27326
27356
  }()
27327
27357
  /**
27328
27358
  * Prime AudioContext with silent buffer to initialize Android hardware
27329
27359
  * This prevents the first audio frame from being cut off on Android devices
27330
27360
  */
27331
- )
27332
27361
  }, {
27333
27362
  key: "_primeAudioContext",
27334
27363
  value: (function () {
27335
- var _primeAudioContext2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
27364
+ var _primeAudioContext2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
27336
27365
  var sampleRate, silentBuffer, source, _t5;
27337
- return _regenerator().w(function (_context9) {
27338
- while (1) switch (_context9.p = _context9.n) {
27366
+ return _regenerator().w(function (_context0) {
27367
+ while (1) switch (_context0.p = _context0.n) {
27339
27368
  case 0:
27340
- _context9.p = 0;
27369
+ _context0.p = 0;
27341
27370
  if (!(!this.audioContext || this._audioContextPrimed)) {
27342
- _context9.n = 1;
27371
+ _context0.n = 1;
27343
27372
  break;
27344
27373
  }
27345
- return _context9.a(2);
27374
+ return _context0.a(2);
27346
27375
  case 1:
27347
27376
  sampleRate = this.audioContext.sampleRate;
27348
27377
  silentBuffer = this.audioContext.createBuffer(1, sampleRate * 0.15, sampleRate);
@@ -27353,23 +27382,23 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27353
27382
  source.connect(this.gainNode || this.audioContext.destination);
27354
27383
  source.start();
27355
27384
  this._ensureHtmlAudioPlaying();
27356
- _context9.n = 2;
27385
+ _context0.n = 2;
27357
27386
  return new Promise(function (resolve) {
27358
27387
  return setTimeout(resolve, 150);
27359
27388
  });
27360
27389
  case 2:
27361
27390
  this._audioContextPrimed = true;
27362
27391
  console.log('✅ AudioPlayer: Audio hardware primed with silent buffer');
27363
- _context9.n = 4;
27392
+ _context0.n = 4;
27364
27393
  break;
27365
27394
  case 3:
27366
- _context9.p = 3;
27367
- _t5 = _context9.v;
27395
+ _context0.p = 3;
27396
+ _t5 = _context0.v;
27368
27397
  console.error('❌ AudioPlayer: Audio priming failed:', _t5);
27369
27398
  case 4:
27370
- return _context9.a(2);
27399
+ return _context0.a(2);
27371
27400
  }
27372
- }, _callee8, this, [[0, 3]]);
27401
+ }, _callee9, this, [[0, 3]]);
27373
27402
  }));
27374
27403
  function _primeAudioContext() {
27375
27404
  return _primeAudioContext2.apply(this, arguments);
@@ -27436,7 +27465,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27436
27465
  * Handles mic permission grants, tab switching, browser suspension, etc.
27437
27466
  */
27438
27467
  function setupAudioContextStateMonitoring() {
27439
- var _this9 = this;
27468
+ var _this0 = this;
27440
27469
  if (!this.audioContext) {
27441
27470
  return;
27442
27471
  }
@@ -27449,38 +27478,38 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27449
27478
  // Create handler that references this.audioContext dynamically
27450
27479
  this._audioContextStateChangeHandler = function () {
27451
27480
  // Null check required because audioContext may be cleaned up while handler is queued
27452
- if (!_this9.audioContext) {
27481
+ if (!_this0.audioContext) {
27453
27482
  console.warn('⚠️ AudioPlayer: State change handler fired but AudioContext is null');
27454
27483
  return;
27455
27484
  }
27456
- console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(_this9.audioContext.state));
27457
- if (_this9.audioContext.state === 'running') {
27458
- _this9._ensureHtmlAudioPlaying();
27485
+ console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(_this0.audioContext.state));
27486
+ if (_this0.audioContext.state === 'running') {
27487
+ _this0._ensureHtmlAudioPlaying();
27459
27488
  }
27460
- if (_this9.audioContext.state === 'suspended' && _this9.isPlaying) {
27489
+ if (_this0.audioContext.state === 'suspended' && _this0.isPlaying) {
27461
27490
  // AudioContext was suspended during playback (tab switch, mic permission, etc.)
27462
27491
  console.warn('⚠️ AudioPlayer: AudioContext suspended during playback');
27463
27492
  // Note: Playback will pause automatically, but we should handle queue processing
27464
27493
  // The state change will be handled when we try to process next frame
27465
- } else if (_this9.audioContext.state === 'running' && !_this9.isPlaying && (_this9.audioQueue.length > 0 || _this9.pcmChunkQueue.length > 0 || _this9.preparedBuffer.length > 0)) {
27494
+ } else if (_this0.audioContext.state === 'running' && !_this0.isPlaying && (_this0.audioQueue.length > 0 || _this0.pcmChunkQueue.length > 0 || _this0.preparedBuffer.length > 0)) {
27466
27495
  // AudioContext resumed and we have queued frames
27467
27496
  // This handles: mic permission grant, tab switching back, browser resume, etc.
27468
27497
  console.log('✅ AudioPlayer: AudioContext resumed - resuming queue processing');
27469
27498
 
27470
27499
  // Resume queue processing if we have frames
27471
- if (_this9.audioQueue.length > 0 && !_this9.isProcessingQueue) {
27500
+ if (_this0.audioQueue.length > 0 && !_this0.isProcessingQueue) {
27472
27501
  setTimeout(function () {
27473
- return _this9.processQueue();
27502
+ return _this0.processQueue();
27474
27503
  }, 50);
27475
27504
  }
27476
- if (_this9.pcmChunkQueue.length > 0 && !_this9.isProcessingPcmQueue) {
27505
+ if (_this0.pcmChunkQueue.length > 0 && !_this0.isProcessingPcmQueue) {
27477
27506
  setTimeout(function () {
27478
- return _this9.processPcmQueue();
27507
+ return _this0.processPcmQueue();
27479
27508
  }, 50);
27480
27509
  }
27481
- if (_this9.preparedBuffer.length > 0 && !_this9.isSchedulingFrames) {
27510
+ if (_this0.preparedBuffer.length > 0 && !_this0.isSchedulingFrames) {
27482
27511
  setTimeout(function () {
27483
- return _this9.scheduleFrames();
27512
+ return _this0.scheduleFrames();
27484
27513
  }, 50);
27485
27514
  }
27486
27515
  }
@@ -27498,49 +27527,49 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27498
27527
  }, {
27499
27528
  key: "processQueue",
27500
27529
  value: (function () {
27501
- var _processQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
27502
- var _this0 = this;
27530
+ var _processQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
27531
+ var _this1 = this;
27503
27532
  var audioBlob, wasFirstPlay, audioContext, arrayBuffer, audioBuffer, shouldEmitStart, source, _t6;
27504
- return _regenerator().w(function (_context0) {
27505
- while (1) switch (_context0.p = _context0.n) {
27533
+ return _regenerator().w(function (_context1) {
27534
+ while (1) switch (_context1.p = _context1.n) {
27506
27535
  case 0:
27507
27536
  if (!this._isStopped) {
27508
- _context0.n = 1;
27537
+ _context1.n = 1;
27509
27538
  break;
27510
27539
  }
27511
27540
  console.log('🛑 AudioPlayer: Not processing queue - playback was stopped (barge-in)');
27512
- return _context0.a(2);
27541
+ return _context1.a(2);
27513
27542
  case 1:
27514
27543
  if (!(this.isProcessingQueue || this.audioQueue.length === 0)) {
27515
- _context0.n = 2;
27544
+ _context1.n = 2;
27516
27545
  break;
27517
27546
  }
27518
- return _context0.a(2);
27547
+ return _context1.a(2);
27519
27548
  case 2:
27520
27549
  this.isProcessingQueue = true;
27521
27550
  this._ensureHtmlAudioPlaying();
27522
27551
  audioBlob = this.audioQueue.shift();
27523
27552
  if (audioBlob) {
27524
- _context0.n = 3;
27553
+ _context1.n = 3;
27525
27554
  break;
27526
27555
  }
27527
27556
  this.isProcessingQueue = false;
27528
- return _context0.a(2);
27557
+ return _context1.a(2);
27529
27558
  case 3:
27530
- _context0.p = 3;
27559
+ _context1.p = 3;
27531
27560
  wasFirstPlay = !this.isPlaying && this.currentSource === null; // Ensure context exists and is running (handles lazy init + suspended shared context)
27532
- _context0.n = 4;
27561
+ _context1.n = 4;
27533
27562
  return this.waitForAudioContextReady();
27534
27563
  case 4:
27535
27564
  audioContext = this.audioContext; // Decode audio
27536
- _context0.n = 5;
27565
+ _context1.n = 5;
27537
27566
  return audioBlob.arrayBuffer();
27538
27567
  case 5:
27539
- arrayBuffer = _context0.v;
27540
- _context0.n = 6;
27568
+ arrayBuffer = _context1.v;
27569
+ _context1.n = 6;
27541
27570
  return audioContext.decodeAudioData(arrayBuffer);
27542
27571
  case 6:
27543
- audioBuffer = _context0.v;
27572
+ audioBuffer = _context1.v;
27544
27573
  shouldEmitStart = wasFirstPlay && !this.isPlaying && this.currentSource === null; // Create source
27545
27574
  source = audioContext.createBufferSource();
27546
27575
  source.buffer = audioBuffer;
@@ -27559,22 +27588,22 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27559
27588
  // Handle end
27560
27589
 
27561
27590
  source.onended = function () {
27562
- _this0.currentSource = null;
27563
- _this0.isProcessingQueue = false;
27591
+ _this1.currentSource = null;
27592
+ _this1.isProcessingQueue = false;
27564
27593
 
27565
27594
  // Process next chunk
27566
27595
 
27567
- if (_this0.audioQueue.length > 0) {
27596
+ if (_this1.audioQueue.length > 0) {
27568
27597
  setTimeout(function () {
27569
- return _this0.processQueue();
27598
+ return _this1.processQueue();
27570
27599
  }, 50);
27571
27600
  } else {
27572
27601
  // No more chunks - stop after delay
27573
27602
 
27574
27603
  setTimeout(function () {
27575
- if (_this0.audioQueue.length === 0 && !_this0.currentSource) {
27576
- _this0.isPlaying = false;
27577
- _this0.emit('playbackStopped');
27604
+ if (_this1.audioQueue.length === 0 && !_this1.currentSource) {
27605
+ _this1.isPlaying = false;
27606
+ _this1.emit('playbackStopped');
27578
27607
  }
27579
27608
  }, 100);
27580
27609
  }
@@ -27583,11 +27612,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27583
27612
  // Start playback - AudioContext should now be fully ready
27584
27613
 
27585
27614
  source.start();
27586
- _context0.n = 8;
27615
+ _context1.n = 8;
27587
27616
  break;
27588
27617
  case 7:
27589
- _context0.p = 7;
27590
- _t6 = _context0.v;
27618
+ _context1.p = 7;
27619
+ _t6 = _context1.v;
27591
27620
  console.error('❌ AudioPlayer v2: Error processing queue:', _t6);
27592
27621
  this.currentSource = null;
27593
27622
  this.emit('playbackError', _t6);
@@ -27597,7 +27626,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27597
27626
  if (this.audioQueue.length > 0) {
27598
27627
  this.isProcessingQueue = false;
27599
27628
  setTimeout(function () {
27600
- return _this0.processQueue();
27629
+ return _this1.processQueue();
27601
27630
  }, 100);
27602
27631
  } else {
27603
27632
  this.isPlaying = false;
@@ -27605,9 +27634,9 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27605
27634
  this.emit('playbackStopped');
27606
27635
  }
27607
27636
  case 8:
27608
- return _context0.a(2);
27637
+ return _context1.a(2);
27609
27638
  }
27610
- }, _callee9, this, [[3, 7]]);
27639
+ }, _callee0, this, [[3, 7]]);
27611
27640
  }));
27612
27641
  function processQueue() {
27613
27642
  return _processQueue.apply(this, arguments);
@@ -27820,7 +27849,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27820
27849
  }, {
27821
27850
  key: "markNewSentence",
27822
27851
  value: function markNewSentence(text, synced, segmentId) {
27823
- var _this1 = this;
27852
+ var _this10 = this;
27824
27853
  var wasStopped = this._isStopped;
27825
27854
  var isCurrentlyPlaying = this.isPlaying || this.scheduledSources.size > 0;
27826
27855
 
@@ -27879,34 +27908,34 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27879
27908
  var sentenceText = text; // Capture for timeout callback
27880
27909
  this._emptySentenceTimeout = setTimeout(function () {
27881
27910
  // Check if this sentence still has no chunks after timeout
27882
- if (_this1.pendingSentenceText === sentenceText && _this1.scheduledBuffers === 0 && _this1.preparedBuffer.length === 0 && _this1.pcmChunkQueue.length === 0 && !_this1._isStopped) {
27911
+ if (_this10.pendingSentenceText === sentenceText && _this10.scheduledBuffers === 0 && _this10.preparedBuffer.length === 0 && _this10.pcmChunkQueue.length === 0 && !_this10._isStopped) {
27883
27912
  console.warn("\u26A0\uFE0F AudioPlayer: Empty sentence detected after 5s timeout - no chunks received for: \"".concat(sentenceText.substring(0, 40), "...\""));
27884
27913
  // If this empty sentence carried a segment id, report it done (nothing was heard) and
27885
27914
  // adopt it as current so the coarse stop below matches the backend's last-sent id.
27886
- if (_this1.pendingSegmentId != null) {
27887
- var emptySegId = _this1.pendingSegmentId;
27888
- _this1.currentSegmentId = emptySegId;
27889
- _this1.pendingSegmentId = null;
27890
- _this1.emit('segmentDone', {
27915
+ if (_this10.pendingSegmentId != null) {
27916
+ var emptySegId = _this10.pendingSegmentId;
27917
+ _this10.currentSegmentId = emptySegId;
27918
+ _this10.pendingSegmentId = null;
27919
+ _this10.emit('segmentDone', {
27891
27920
  segmentId: emptySegId,
27892
27921
  status: 'finished',
27893
27922
  playedMs: 0
27894
27923
  });
27895
27924
  }
27896
27925
  // Clear pending sentence to unblock next sentence
27897
- if (_this1.pendingSentenceText === sentenceText) {
27898
- _this1.pendingSentenceText = null;
27926
+ if (_this10.pendingSentenceText === sentenceText) {
27927
+ _this10.pendingSentenceText = null;
27899
27928
  }
27900
27929
  // Emit playbackStopped to allow next sentence to start
27901
27930
  // Only if we're not currently playing (to avoid interrupting real playback)
27902
- if (!_this1.isPlaying && _this1.scheduledSources.size === 0) {
27931
+ if (!_this10.isPlaying && _this10.scheduledSources.size === 0) {
27903
27932
  console.log('🛑 AudioPlayer: Emitting playbackStopped for empty sentence timeout');
27904
- _this1.emit('playbackStopped', {
27905
- segmentId: _this1.currentSegmentId
27933
+ _this10.emit('playbackStopped', {
27934
+ segmentId: _this10.currentSegmentId
27906
27935
  });
27907
27936
  }
27908
27937
  }
27909
- _this1._emptySentenceTimeout = null;
27938
+ _this10._emptySentenceTimeout = null;
27910
27939
  }, 5000); // 5 second timeout - adjust based on expected chunk arrival rate
27911
27940
  }
27912
27941
 
@@ -27916,14 +27945,14 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27916
27945
  }, {
27917
27946
  key: "startTranscriptChecker",
27918
27947
  value: function startTranscriptChecker() {
27919
- var _this10 = this;
27948
+ var _this11 = this;
27920
27949
  if (this.isCheckingTranscripts) return;
27921
27950
  this.isCheckingTranscripts = true;
27922
27951
  console.log('📝 AudioPlayer: Transcript checker started');
27923
27952
  var _checkLoop = function checkLoop() {
27924
- if (!_this10.isCheckingTranscripts || !_this10.audioContext) return;
27925
- var currentTime = _this10.audioContext.currentTime;
27926
- var _iterator2 = _createForOfIteratorHelper(_this10.sentenceTimings),
27953
+ if (!_this11.isCheckingTranscripts || !_this11.audioContext) return;
27954
+ var currentTime = _this11.audioContext.currentTime;
27955
+ var _iterator2 = _createForOfIteratorHelper(_this11.sentenceTimings),
27927
27956
  _step2;
27928
27957
  try {
27929
27958
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
@@ -27937,13 +27966,13 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27937
27966
  eventData.synced = _timing.synced;
27938
27967
  }
27939
27968
  console.log("\uD83D\uDCDD AudioPlayer: Display transcript at ".concat(currentTime.toFixed(3), "s: \"").concat(_timing.text.substring(0, 40), "...\" (synced: ").concat(_timing.synced ? _timing.synced.length : 0, ")"));
27940
- _this10.emit('transcriptDisplay', eventData);
27969
+ _this11.emit('transcriptDisplay', eventData);
27941
27970
  }
27942
27971
  // Per-segment natural finish: this segment's audio window has fully elapsed.
27943
27972
  if (!_timing.doneReported && _timing.endTime != null && currentTime >= _timing.endTime) {
27944
27973
  _timing.doneReported = true;
27945
27974
  var _playedMs = Math.round((_timing.endTime - _timing.startTime) * 1000);
27946
- _this10.emit('segmentDone', {
27975
+ _this11.emit('segmentDone', {
27947
27976
  segmentId: _timing.segmentId,
27948
27977
  status: 'finished',
27949
27978
  playedMs: _playedMs
@@ -27955,12 +27984,12 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27955
27984
  } finally {
27956
27985
  _iterator2.f();
27957
27986
  }
27958
- if (_this10.isPlaying || _this10.scheduledBuffers > 0) {
27987
+ if (_this11.isPlaying || _this11.scheduledBuffers > 0) {
27959
27988
  requestAnimationFrame(_checkLoop);
27960
27989
  } else {
27961
27990
  // Playback drained naturally — flush any segment whose finish tick we may have missed
27962
27991
  // (the last buffer's onended can flip isPlaying=false before this loop's next tick).
27963
- var _iterator3 = _createForOfIteratorHelper(_this10.sentenceTimings),
27992
+ var _iterator3 = _createForOfIteratorHelper(_this11.sentenceTimings),
27964
27993
  _step3;
27965
27994
  try {
27966
27995
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
@@ -27969,7 +27998,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27969
27998
  timing.doneReported = true;
27970
27999
  var end = timing.endTime != null ? timing.endTime : timing.startTime;
27971
28000
  var playedMs = Math.round((end - timing.startTime) * 1000);
27972
- _this10.emit('segmentDone', {
28001
+ _this11.emit('segmentDone', {
27973
28002
  segmentId: timing.segmentId,
27974
28003
  status: 'finished',
27975
28004
  playedMs: playedMs
@@ -27981,7 +28010,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27981
28010
  } finally {
27982
28011
  _iterator3.f();
27983
28012
  }
27984
- _this10.isCheckingTranscripts = false;
28013
+ _this11.isCheckingTranscripts = false;
27985
28014
  console.log('📝 AudioPlayer: Transcript checker stopped');
27986
28015
  }
27987
28016
  };
@@ -28012,43 +28041,43 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
28012
28041
  }, {
28013
28042
  key: "resumeAudioContext",
28014
28043
  value: (function () {
28015
- var _resumeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
28044
+ var _resumeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee1() {
28016
28045
  var _t7;
28017
- return _regenerator().w(function (_context1) {
28018
- while (1) switch (_context1.p = _context1.n) {
28046
+ return _regenerator().w(function (_context10) {
28047
+ while (1) switch (_context10.p = _context10.n) {
28019
28048
  case 0:
28020
28049
  if (!(!this.audioContext || this.audioContext.state === 'closed')) {
28021
- _context1.n = 2;
28050
+ _context10.n = 2;
28022
28051
  break;
28023
28052
  }
28024
- _context1.n = 1;
28053
+ _context10.n = 1;
28025
28054
  return this.initializeAudioContext();
28026
28055
  case 1:
28027
- _context1.n = 6;
28056
+ _context10.n = 6;
28028
28057
  break;
28029
28058
  case 2:
28030
28059
  if (!(this.audioContext.state === 'suspended')) {
28031
- _context1.n = 6;
28060
+ _context10.n = 6;
28032
28061
  break;
28033
28062
  }
28034
- _context1.p = 3;
28035
- _context1.n = 4;
28063
+ _context10.p = 3;
28064
+ _context10.n = 4;
28036
28065
  return this.audioContext.resume();
28037
28066
  case 4:
28038
28067
  console.log('✅ AudioPlayer v2: AudioContext resumed after mic permission');
28039
- _context1.n = 6;
28068
+ _context10.n = 6;
28040
28069
  break;
28041
28070
  case 5:
28042
- _context1.p = 5;
28043
- _t7 = _context1.v;
28071
+ _context10.p = 5;
28072
+ _t7 = _context10.v;
28044
28073
  console.warn('⚠️ AudioPlayer v2: Failed to resume AudioContext:', _t7);
28045
28074
  case 6:
28046
- _context1.n = 7;
28075
+ _context10.n = 7;
28047
28076
  return this.waitForAudioContextReady();
28048
28077
  case 7:
28049
- return _context1.a(2);
28078
+ return _context10.a(2);
28050
28079
  }
28051
- }, _callee0, this, [[3, 5]]);
28080
+ }, _callee1, this, [[3, 5]]);
28052
28081
  }));
28053
28082
  function resumeAudioContext() {
28054
28083
  return _resumeAudioContext.apply(this, arguments);
@@ -29141,7 +29170,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29141
29170
  // iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
29142
29171
  var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
29143
29172
  var env = {
29144
- sdkVersion: true ? "2.48.2" : 0,
29173
+ sdkVersion: true ? "2.48.5" : 0,
29145
29174
  ua: ua,
29146
29175
  platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
29147
29176
  mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
@@ -29156,7 +29185,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29156
29185
  } catch (e) {
29157
29186
  console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
29158
29187
  return {
29159
- sdkVersion: true ? "2.48.2" : 0
29188
+ sdkVersion: true ? "2.48.5" : 0
29160
29189
  };
29161
29190
  }
29162
29191
  }
@@ -29298,7 +29327,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29298
29327
 
29299
29328
  // Include SDK build time for debugging
29300
29329
  if (true) {
29301
- helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
29330
+ helloMessage.lastBuildTime = "2026-08-20T16:29:04.205Z";
29302
29331
  }
29303
29332
 
29304
29333
  // Client environment (device/browser/webview) for backend logs + Langfuse metadata
@@ -35348,7 +35377,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
35348
35377
  return;
35349
35378
  }
35350
35379
  this._ensureAboutStyles();
35351
- var version = true ? "2.48.2" : 0;
35380
+ var version = true ? "2.48.5" : 0;
35352
35381
  var convId = this._getLastConversationId();
35353
35382
  var t = function t(k, fb) {
35354
35383
  try {