ttp-agent-sdk 2.48.5 → 2.48.7

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-20T16:29:04.205Z";
12050
+ helloMessage.lastBuildTime = "2026-08-20T21:16:40.754Z";
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.5";
21361
- var BUILD_TIME = "2026-08-20T16:29:04.205Z";
21360
+ var VERSION = "2.48.7";
21361
+ var BUILD_TIME = "2026-08-20T21:16:40.754Z";
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
@@ -25569,6 +25569,49 @@ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf
25569
25569
  // so creating a new AudioContext immediately after closing the old one can fail silently.
25570
25570
  var _sharedPlayerContext = null;
25571
25571
  var _sharedPlayerSampleRate = null;
25572
+ function _sinc(x) {
25573
+ if (x === 0) return 1;
25574
+ var px = Math.PI * x;
25575
+ return Math.sin(px) / px;
25576
+ }
25577
+ function _blackman(x) {
25578
+ var n = (x + 1) / 2;
25579
+ return 0.42 - 0.5 * Math.cos(2 * Math.PI * n) + 0.08 * Math.cos(4 * Math.PI * n);
25580
+ }
25581
+
25582
+ /**
25583
+ * Windowed-sinc resampler (16 taps, anti-aliased on downsample). Used only when
25584
+ * the HTML-audio hop ended up on a low-rate context (e.g. Bluetooth hands-free
25585
+ * caps output at 16 kHz): the MediaStream → <audio> hop is not reliable unless
25586
+ * the stream honestly runs at context.sampleRate, so TTS PCM is resampled
25587
+ * before createBuffer — the same invariant ElevenLabs keeps in its
25588
+ * audioConcatProcessor worklet.
25589
+ */
25590
+ function resampleFloat32ToRate(input, fromRate, toRate) {
25591
+ if (fromRate === toRate || !input || input.length === 0) return input;
25592
+ var ratio = fromRate / toRate;
25593
+ var outLength = Math.max(1, Math.round(input.length / ratio));
25594
+ var out = new Float32Array(outLength);
25595
+ var TAPS = 16;
25596
+ var HALF = TAPS / 2;
25597
+ var cutoff = 0.92 * Math.min(1, toRate / fromRate);
25598
+ for (var i = 0; i < outLength; i++) {
25599
+ var pos = i * ratio;
25600
+ var center = Math.floor(pos);
25601
+ var sum = 0;
25602
+ var wsum = 0;
25603
+ for (var t = -HALF + 1; t <= HALF; t++) {
25604
+ var idx = center + t;
25605
+ if (idx < 0 || idx >= input.length) continue;
25606
+ var x = pos - idx;
25607
+ var w = _blackman(t / HALF) * _sinc(x * cutoff) * cutoff;
25608
+ sum += input[idx] * w;
25609
+ wsum += w;
25610
+ }
25611
+ out[i] = wsum !== 0 ? sum / wsum : 0;
25612
+ }
25613
+ return out;
25614
+ }
25572
25615
 
25573
25616
  /**
25574
25617
 
@@ -25620,6 +25663,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25620
25663
  _this._mediaStreamDest = null;
25621
25664
  _this._htmlAudioRouteActive = false;
25622
25665
  _this._htmlAudioPlayOk = false;
25666
+ _this._loggedHopResample = false;
25623
25667
  // Greeting (and other bursts) fire many playChunk()s without await.
25624
25668
  // Serialize context creation so they cannot open two AudioContexts
25625
25669
  // at different rates in the middle of a sentence.
@@ -25915,7 +25959,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25915
25959
  key: "prepareChunk",
25916
25960
  value: (function () {
25917
25961
  var _prepareChunk = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(pcmData) {
25918
- var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, audioBuffer, actualDuration, _t;
25962
+ var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, playback, audioBuffer, actualDuration, _t;
25919
25963
  return _regenerator().w(function (_context2) {
25920
25964
  while (1) switch (_context2.p = _context2.n) {
25921
25965
  case 0:
@@ -25964,11 +26008,12 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25964
26008
 
25965
26009
  // Create audio buffer with the ACTUAL sample rate of the audio data
25966
26010
  audioDataSampleRate = ((_this$outputFormat2 = this.outputFormat) === null || _this$outputFormat2 === void 0 ? void 0 : _this$outputFormat2.sampleRate) || this.audioContext.sampleRate;
26011
+ playback = this._honestRateSamples(float32Array, audioDataSampleRate);
25967
26012
  audioBuffer = this.audioContext.createBuffer(1,
25968
26013
  // mono
25969
26014
 
25970
- float32Array.length, audioDataSampleRate);
25971
- audioBuffer.getChannelData(0).set(float32Array);
26015
+ playback.samples.length, playback.sampleRate);
26016
+ audioBuffer.getChannelData(0).set(playback.samples);
25972
26017
 
25973
26018
  // Wall-clock duration is sampleCount / TTS rate (audioBuffer.duration).
25974
26019
  // Dividing by contextSampleRate when the context is 48 kHz and TTS is
@@ -26335,7 +26380,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26335
26380
  value: (function () {
26336
26381
  var _processPcmQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
26337
26382
  var _this5 = this;
26338
- var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, actualDuration, startTime, _t3;
26383
+ var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, playback, audioBuffer, source, currentTime, actualDuration, startTime, _t3;
26339
26384
  return _regenerator().w(function (_context5) {
26340
26385
  while (1) switch (_context5.p = _context5.n) {
26341
26386
  case 0:
@@ -26402,10 +26447,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26402
26447
  } else if (this.scheduledBuffers < 3) {
26403
26448
  console.log("\uD83C\uDFB5 AudioPlayer: Creating buffer at ".concat(audioDataSampleRate, "Hz (AudioContext: ").concat(contextSampleRate, "Hz)"));
26404
26449
  }
26450
+ playback = this._honestRateSamples(float32Array, audioDataSampleRate);
26405
26451
  audioBuffer = this.audioContext.createBuffer(1,
26406
26452
  // mono
26407
- float32Array.length, audioDataSampleRate);
26408
- audioBuffer.getChannelData(0).set(float32Array);
26453
+ playback.samples.length, playback.sampleRate);
26454
+ audioBuffer.getChannelData(0).set(playback.samples);
26409
26455
 
26410
26456
  // Schedule playback with seamless timing
26411
26457
  source = this.audioContext.createBufferSource();
@@ -27061,6 +27107,34 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27061
27107
  value: function _isHardwarePlaybackRate(rate) {
27062
27108
  return typeof rate === 'number' && rate >= 44100;
27063
27109
  }
27110
+
27111
+ /**
27112
+ * HTML-hop mismatch guard. The MediaStreamDestination → <audio> hop is only
27113
+ * reliable when the context runs at a hardware rate; if Chrome still gave a
27114
+ * low-rate context (e.g. Bluetooth hands-free output), resample the TTS audio
27115
+ * to the context rate ourselves so the stream honestly runs at
27116
+ * context.sampleRate. Destination playback is untouched — Web Audio resamples
27117
+ * correctly on that path.
27118
+ */
27119
+ }, {
27120
+ key: "_honestRateSamples",
27121
+ value: function _honestRateSamples(float32Array, audioDataSampleRate) {
27122
+ var contextRate = this.audioContext.sampleRate;
27123
+ if (this._htmlHopNeedsHardwareRate() && !this._isHardwarePlaybackRate(contextRate) && audioDataSampleRate !== contextRate) {
27124
+ if (!this._loggedHopResample) {
27125
+ this._loggedHopResample = true;
27126
+ console.warn("\u26A0\uFE0F AudioPlayer: HTML hop on a ".concat(contextRate, "Hz context \u2014 resampling TTS ").concat(audioDataSampleRate, "Hz \u2192 ").concat(contextRate, "Hz in the player"));
27127
+ }
27128
+ return {
27129
+ samples: resampleFloat32ToRate(float32Array, audioDataSampleRate, contextRate),
27130
+ sampleRate: contextRate
27131
+ };
27132
+ }
27133
+ return {
27134
+ samples: float32Array,
27135
+ sampleRate: audioDataSampleRate
27136
+ };
27137
+ }
27064
27138
  }, {
27065
27139
  key: "getHtmlAudioPlaybackInfo",
27066
27140
  value: function getHtmlAudioPlaybackInfo() {
@@ -27214,9 +27288,12 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27214
27288
  while (1) switch (_context9.p = _context9.n) {
27215
27289
  case 0:
27216
27290
  ttsSampleRate = this._ttsSampleRate();
27217
- useHardwareRate = this._htmlHopNeedsHardwareRate(); // Destination path: match TTS (24 kHz). HTML last-hop: omit so the
27218
- // context (and MediaStream) run at the device rate usually 48 kHz.
27219
- desiredSampleRate = useHardwareRate ? null : ttsSampleRate;
27291
+ useHardwareRate = this._htmlHopNeedsHardwareRate(); // Destination path: match TTS (24 kHz). HTML last-hop: request the standard
27292
+ // hardware rate explicitly. Omitting it lets Chrome inherit whatever rate is
27293
+ // already active on the page (the widget opens the 16 kHz mic context before
27294
+ // the player), and the MediaStream → <audio> hop then mis-clocks — heard as
27295
+ // chipmunk-fast or half-speed speech.
27296
+ desiredSampleRate = useHardwareRate ? 48000 : ttsSampleRate;
27220
27297
  if (!useHardwareRate && ![24000, 44100, 48000].includes(desiredSampleRate)) {
27221
27298
  console.log("\u2139\uFE0F AudioPlayer: Backend requested ".concat(desiredSampleRate, "Hz, but browser may resample"));
27222
27299
  console.log(" Consider requesting 24000Hz, 44100Hz, or 48000Hz from backend to reduce resampling");
@@ -27296,7 +27373,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27296
27373
  setupAfterResume();
27297
27374
  return _context9.a(2);
27298
27375
  case 8:
27299
- console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate || 'hardware default', ")"));
27376
+ console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate, "Hz)"));
27300
27377
 
27301
27378
  // Close old shared context if sample rate changed
27302
27379
  if (_sharedPlayerContext && _sharedPlayerContext.state !== 'closed') {
@@ -27321,7 +27398,9 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27321
27398
  _sharedPlayerSampleRate = this.audioContext.sampleRate;
27322
27399
  console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (tts=").concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ")"));
27323
27400
  if (useHardwareRate && !this._isHardwarePlaybackRate(this.audioContext.sampleRate)) {
27324
- console.warn("\u26A0\uFE0F AudioPlayer: HTML hop expected \u226544.1 kHz context, got ".concat(this.audioContext.sampleRate, "Hz"));
27401
+ // The hop stays on; _honestRateSamples resamples TTS to the context rate
27402
+ // per chunk so the MediaStream honestly runs at context.sampleRate.
27403
+ console.warn("\u26A0\uFE0F AudioPlayer: HTML hop got ".concat(this.audioContext.sampleRate, "Hz (<44.1 kHz) \u2014 resampling TTS to the context rate in the player"));
27325
27404
  } else if (!useHardwareRate && Math.abs(this.audioContext.sampleRate - desiredSampleRate) > 100) {
27326
27405
  console.warn("\u26A0\uFE0F AudioPlayer: Browser sample rate ".concat(this.audioContext.sampleRate, "Hz \u2260 requested ").concat(desiredSampleRate, "Hz; Web Audio will resample"));
27327
27406
  }
@@ -29170,7 +29249,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29170
29249
  // iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
29171
29250
  var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
29172
29251
  var env = {
29173
- sdkVersion: true ? "2.48.5" : 0,
29252
+ sdkVersion: true ? "2.48.7" : 0,
29174
29253
  ua: ua,
29175
29254
  platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
29176
29255
  mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
@@ -29185,7 +29264,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29185
29264
  } catch (e) {
29186
29265
  console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
29187
29266
  return {
29188
- sdkVersion: true ? "2.48.5" : 0
29267
+ sdkVersion: true ? "2.48.7" : 0
29189
29268
  };
29190
29269
  }
29191
29270
  }
@@ -29327,7 +29406,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29327
29406
 
29328
29407
  // Include SDK build time for debugging
29329
29408
  if (true) {
29330
- helloMessage.lastBuildTime = "2026-08-20T16:29:04.205Z";
29409
+ helloMessage.lastBuildTime = "2026-08-20T21:16:40.754Z";
29331
29410
  }
29332
29411
 
29333
29412
  // Client environment (device/browser/webview) for backend logs + Langfuse metadata
@@ -35377,7 +35456,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
35377
35456
  return;
35378
35457
  }
35379
35458
  this._ensureAboutStyles();
35380
- var version = true ? "2.48.5" : 0;
35459
+ var version = true ? "2.48.7" : 0;
35381
35460
  var convId = this._getLastConversationId();
35382
35461
  var t = function t(k, fb) {
35383
35462
  try {