ttp-agent-sdk 2.48.1 → 2.48.2

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-20T12:21:14.185Z";
12050
+ helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
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.0";
21361
- var BUILD_TIME = "2026-08-20T12:21:14.185Z";
21360
+ var VERSION = "2.48.2";
21361
+ var BUILD_TIME = "2026-08-20T14:41:57.957Z";
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
@@ -25727,9 +25727,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25727
25727
  this.outputFormat = format;
25728
25728
  console.log('✅ AudioPlayer v2: Format set:', format);
25729
25729
 
25730
- // CRITICAL: If AudioContext already exists and sample rate changed, recreate it
25730
+ // Destination path matches AudioContext to the TTS rate. The HTML last-hop
25731
+ // keeps the context at hardware rate (48 kHz); only createBuffer() follows TTS.
25731
25732
 
25732
- if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate) {
25733
+ if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate && !this._htmlHopNeedsHardwareRate()) {
25733
25734
  console.warn('⚠️ AudioPlayer: Sample rate changed, recreating AudioContext');
25734
25735
  console.warn(" Old: ".concat(oldSampleRate, "Hz \u2192 New: ").concat(newSampleRate, "Hz"));
25735
25736
 
@@ -25910,7 +25911,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25910
25911
  key: "prepareChunk",
25911
25912
  value: (function () {
25912
25913
  var _prepareChunk = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(pcmData) {
25913
- var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, chunkDuration, sampleCount, actualDuration, _t;
25914
+ var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, audioBuffer, actualDuration, _t;
25914
25915
  return _regenerator().w(function (_context2) {
25915
25916
  while (1) switch (_context2.p = _context2.n) {
25916
25917
  case 0:
@@ -25959,27 +25960,21 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
25959
25960
 
25960
25961
  // Create audio buffer with the ACTUAL sample rate of the audio data
25961
25962
  audioDataSampleRate = ((_this$outputFormat2 = this.outputFormat) === null || _this$outputFormat2 === void 0 ? void 0 : _this$outputFormat2.sampleRate) || this.audioContext.sampleRate;
25962
- contextSampleRate = this.audioContext.sampleRate;
25963
25963
  audioBuffer = this.audioContext.createBuffer(1,
25964
25964
  // mono
25965
25965
 
25966
25966
  float32Array.length, audioDataSampleRate);
25967
25967
  audioBuffer.getChannelData(0).set(float32Array);
25968
25968
 
25969
- // Calculate duration (handle browser resampling)
25970
- chunkDuration = audioBuffer.duration;
25971
- sampleCount = float32Array.length;
25972
- actualDuration = chunkDuration;
25973
- if (contextSampleRate !== audioDataSampleRate) {
25974
- actualDuration = sampleCount / contextSampleRate;
25975
- }
25976
-
25977
- // Return prepared frame
25969
+ // Wall-clock duration is sampleCount / TTS rate (audioBuffer.duration).
25970
+ // Dividing by contextSampleRate when the context is 48 kHz and TTS is
25971
+ // 24 kHz halves the schedule step and overlaps chunks.
25972
+ actualDuration = audioBuffer.duration; // Return prepared frame
25978
25973
  return _context2.a(2, {
25979
25974
  buffer: audioBuffer,
25980
25975
  duration: actualDuration,
25981
25976
  sampleRate: audioDataSampleRate,
25982
- contextSampleRate: contextSampleRate
25977
+ contextSampleRate: this.audioContext.sampleRate
25983
25978
  });
25984
25979
  case 4:
25985
25980
  _context2.p = 4;
@@ -26336,7 +26331,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26336
26331
  value: (function () {
26337
26332
  var _processPcmQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
26338
26333
  var _this5 = this;
26339
- var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, chunkDuration, sampleCount, actualDuration, startTime, _t3;
26334
+ var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, actualDuration, startTime, _t3;
26340
26335
  return _regenerator().w(function (_context5) {
26341
26336
  while (1) switch (_context5.p = _context5.n) {
26342
26337
  case 0:
@@ -26423,16 +26418,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
26423
26418
  }
26424
26419
  }
26425
26420
 
26426
- // Calculate frame duration - handle browser resampling correctly
26427
- chunkDuration = audioBuffer.duration;
26428
- sampleCount = float32Array.length;
26429
- actualDuration = chunkDuration;
26430
- if (contextSampleRate !== audioDataSampleRate) {
26431
- actualDuration = sampleCount / contextSampleRate;
26432
- if (this.scheduledBuffers < 3) {
26433
- console.log("\uD83D\uDD04 Resampling detected: ".concat(audioDataSampleRate, "Hz \u2192 ").concat(contextSampleRate, "Hz"));
26434
- console.log(" Buffer duration: ".concat(chunkDuration.toFixed(4), "s, Calculated: ").concat(actualDuration.toFixed(4), "s"));
26435
- }
26421
+ // Wall-clock duration is always sampleCount / TTS rate. Web Audio
26422
+ // resamples into the context; do not divide by contextSampleRate.
26423
+ actualDuration = audioBuffer.duration;
26424
+ if (contextSampleRate !== audioDataSampleRate && this.scheduledBuffers < 3) {
26425
+ console.log("\uD83D\uDD04 AudioPlayer: Buffer ".concat(audioDataSampleRate, "Hz in ").concat(contextSampleRate, "Hz context, duration ").concat(actualDuration.toFixed(4), "s"));
26436
26426
  }
26437
26427
 
26438
26428
  // Schedule this chunk to start at nextStartTime
@@ -27044,6 +27034,29 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27044
27034
  value: function wantsHtmlAudioPlayback() {
27045
27035
  return this.config.htmlAudioPlayback !== false;
27046
27036
  }
27037
+ }, {
27038
+ key: "_ttsSampleRate",
27039
+ value: function _ttsSampleRate() {
27040
+ var _this$outputFormat5;
27041
+ return ((_this$outputFormat5 = this.outputFormat) === null || _this$outputFormat5 === void 0 ? void 0 : _this$outputFormat5.sampleRate) || 24000;
27042
+ }
27043
+
27044
+ /**
27045
+ * Hidden <audio srcObject> clocks a MediaStream at the device rate
27046
+ * (typically 48 kHz). Forcing the AudioContext to the TTS rate (24 kHz)
27047
+ * makes Chrome play that hop ~2×. Destination-only playback can still
27048
+ * match the TTS rate.
27049
+ */
27050
+ }, {
27051
+ key: "_htmlHopNeedsHardwareRate",
27052
+ value: function _htmlHopNeedsHardwareRate() {
27053
+ return this.wantsHtmlAudioPlayback();
27054
+ }
27055
+ }, {
27056
+ key: "_isHardwarePlaybackRate",
27057
+ value: function _isHardwarePlaybackRate(rate) {
27058
+ return typeof rate === 'number' && rate >= 44100;
27059
+ }
27047
27060
  }, {
27048
27061
  key: "getHtmlAudioPlaybackInfo",
27049
27062
  value: function getHtmlAudioPlaybackInfo() {
@@ -27093,6 +27106,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27093
27106
  el.autoplay = true;
27094
27107
  el.controls = false;
27095
27108
  el.preload = 'auto';
27109
+ el.playbackRate = 1;
27096
27110
  el.style.display = 'none';
27097
27111
  el.srcObject = this._mediaStreamDest.stream;
27098
27112
  document.body.appendChild(el);
@@ -27164,16 +27178,16 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27164
27178
  key: "initializeAudioContext",
27165
27179
  value: (function () {
27166
27180
  var _initializeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
27167
- var _this$outputFormat5,
27168
- _this8 = this,
27169
- _this$outputFormat6;
27170
- var desiredSampleRate, currentSampleRate, canReuseShared, setupAfterResume, _t4;
27181
+ var _this8 = this;
27182
+ var ttsSampleRate, useHardwareRate, desiredSampleRate, contextFits, canReuseShared, setupAfterResume, ctxOpts, _t4;
27171
27183
  return _regenerator().w(function (_context8) {
27172
27184
  while (1) switch (_context8.p = _context8.n) {
27173
27185
  case 0:
27174
- // Use negotiated sample rate, default to 24kHz to match typical server/TTS output
27175
- desiredSampleRate = ((_this$outputFormat5 = this.outputFormat) === null || _this$outputFormat5 === void 0 ? void 0 : _this$outputFormat5.sampleRate) || 24000;
27176
- if (![24000, 44100, 48000].includes(desiredSampleRate)) {
27186
+ ttsSampleRate = this._ttsSampleRate();
27187
+ useHardwareRate = this._htmlHopNeedsHardwareRate(); // Destination path: match TTS (24 kHz). HTML last-hop: omit so the
27188
+ // context (and MediaStream) run at the device rate — usually 48 kHz.
27189
+ desiredSampleRate = useHardwareRate ? null : ttsSampleRate;
27190
+ if (!useHardwareRate && ![24000, 44100, 48000].includes(desiredSampleRate)) {
27177
27191
  console.log("\u2139\uFE0F AudioPlayer: Backend requested ".concat(desiredSampleRate, "Hz, but browser may resample"));
27178
27192
  console.log(" Consider requesting 24000Hz, 44100Hz, or 48000Hz from backend to reduce resampling");
27179
27193
  }
@@ -27181,8 +27195,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27181
27195
  _sharedPlayerContext = null;
27182
27196
  _sharedPlayerSampleRate = null;
27183
27197
  }
27184
-
27185
- // Check if current instance AudioContext exists and matches
27198
+ contextFits = function contextFits(rate) {
27199
+ if (useHardwareRate) return _this8._isHardwarePlaybackRate(rate);
27200
+ return Math.abs(rate - desiredSampleRate) <= 100;
27201
+ }; // Check if current instance AudioContext exists and matches
27186
27202
  if (!this.audioContext) {
27187
27203
  _context8.n = 3;
27188
27204
  break;
@@ -27195,29 +27211,26 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27195
27211
  _context8.n = 3;
27196
27212
  break;
27197
27213
  case 1:
27198
- currentSampleRate = this.audioContext.sampleRate;
27199
- if (!(Math.abs(currentSampleRate - desiredSampleRate) > 100)) {
27214
+ if (!contextFits(this.audioContext.sampleRate)) {
27200
27215
  _context8.n = 2;
27201
27216
  break;
27202
27217
  }
27203
- console.warn("\u26A0\uFE0F AudioPlayer: AudioContext sample rate (".concat(currentSampleRate, "Hz) doesn't match format (").concat(desiredSampleRate, "Hz), recreating..."));
27204
- this.stopImmediate();
27205
- this._cleanupAudioContext();
27206
- _context8.n = 3;
27207
- break;
27208
- case 2:
27209
27218
  this._ensureHtmlAudioPlaying();
27210
27219
  return _context8.a(2);
27220
+ case 2:
27221
+ console.warn("\u26A0\uFE0F AudioPlayer: AudioContext sample rate (".concat(this.audioContext.sampleRate, "Hz) doesn't match playback hop, recreating..."));
27222
+ this.stopImmediate();
27223
+ this._cleanupAudioContext();
27211
27224
  case 3:
27212
27225
  // iOS FIX: Reuse shared AudioContext if available and compatible.
27213
27226
  // iOS WebKit doesn't release audio hardware synchronously on AudioContext.close(),
27214
27227
  // causing newly created AudioContexts to fail silently.
27215
- canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && _sharedPlayerSampleRate === desiredSampleRate;
27228
+ canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && contextFits(_sharedPlayerContext.sampleRate);
27216
27229
  if (!canReuseShared) {
27217
27230
  _context8.n = 8;
27218
27231
  break;
27219
27232
  }
27220
- console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(desiredSampleRate, "Hz (iOS-safe)"));
27233
+ console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(_sharedPlayerContext.sampleRate, "Hz (iOS-safe)"));
27221
27234
  this.audioContext = _sharedPlayerContext;
27222
27235
  setupAfterResume = function setupAfterResume() {
27223
27236
  _this8.setupAudioContextStateMonitoring();
@@ -27253,7 +27266,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27253
27266
  setupAfterResume();
27254
27267
  return _context8.a(2);
27255
27268
  case 8:
27256
- console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext at ".concat(desiredSampleRate, "Hz (from outputFormat: ").concat(((_this$outputFormat6 = this.outputFormat) === null || _this$outputFormat6 === void 0 ? void 0 : _this$outputFormat6.sampleRate) || 'not set', ")"));
27269
+ console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate || 'hardware default', ")"));
27257
27270
 
27258
27271
  // Close old shared context if sample rate changed
27259
27272
  if (_sharedPlayerContext && _sharedPlayerContext.state !== 'closed') {
@@ -27265,24 +27278,22 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
27265
27278
  }
27266
27279
  }
27267
27280
  try {
27268
- this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
27269
- sampleRate: desiredSampleRate,
27281
+ ctxOpts = {
27270
27282
  latencyHint: 'playback'
27271
- });
27283
+ };
27284
+ if (desiredSampleRate) {
27285
+ ctxOpts.sampleRate = desiredSampleRate;
27286
+ }
27287
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)(ctxOpts);
27272
27288
 
27273
27289
  // Store as shared context
27274
27290
  _sharedPlayerContext = this.audioContext;
27275
- _sharedPlayerSampleRate = desiredSampleRate;
27276
- console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (requested: ").concat(desiredSampleRate, "Hz)"));
27277
- if (Math.abs(this.audioContext.sampleRate - desiredSampleRate) > 100) {
27278
- console.error("\u274C CRITICAL: Browser sample rate mismatch!");
27279
- console.error(" Requested: ".concat(desiredSampleRate, "Hz"));
27280
- console.error(" Got: ".concat(this.audioContext.sampleRate, "Hz"));
27281
- console.error(" This WILL cause audio distortion/noise!");
27282
- console.error(" Solution: Backend should send ".concat(this.audioContext.sampleRate, "Hz audio instead"));
27283
- } else if (this.audioContext.sampleRate !== desiredSampleRate) {
27284
- console.warn("\u26A0\uFE0F Browser adjusted sample rate: ".concat(desiredSampleRate, "Hz \u2192 ").concat(this.audioContext.sampleRate, "Hz"));
27285
- console.warn(" Browser will automatically resample audio.");
27291
+ _sharedPlayerSampleRate = this.audioContext.sampleRate;
27292
+ console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (tts=").concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ")"));
27293
+ if (useHardwareRate && !this._isHardwarePlaybackRate(this.audioContext.sampleRate)) {
27294
+ console.warn("\u26A0\uFE0F AudioPlayer: HTML hop expected \u226544.1 kHz context, got ".concat(this.audioContext.sampleRate, "Hz"));
27295
+ } else if (!useHardwareRate && Math.abs(this.audioContext.sampleRate - desiredSampleRate) > 100) {
27296
+ console.warn("\u26A0\uFE0F AudioPlayer: Browser sample rate ".concat(this.audioContext.sampleRate, "Hz \u2260 requested ").concat(desiredSampleRate, "Hz; Web Audio will resample"));
27286
27297
  }
27287
27298
  this.setupAudioContextStateMonitoring();
27288
27299
  this.gainNode = this.audioContext.createGain();
@@ -29130,7 +29141,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29130
29141
  // iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
29131
29142
  var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
29132
29143
  var env = {
29133
- sdkVersion: true ? "2.48.0" : 0,
29144
+ sdkVersion: true ? "2.48.2" : 0,
29134
29145
  ua: ua,
29135
29146
  platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
29136
29147
  mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
@@ -29145,7 +29156,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29145
29156
  } catch (e) {
29146
29157
  console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
29147
29158
  return {
29148
- sdkVersion: true ? "2.48.0" : 0
29159
+ sdkVersion: true ? "2.48.2" : 0
29149
29160
  };
29150
29161
  }
29151
29162
  }
@@ -29287,7 +29298,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
29287
29298
 
29288
29299
  // Include SDK build time for debugging
29289
29300
  if (true) {
29290
- helloMessage.lastBuildTime = "2026-08-20T12:21:14.185Z";
29301
+ helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
29291
29302
  }
29292
29303
 
29293
29304
  // Client environment (device/browser/webview) for backend logs + Langfuse metadata
@@ -35337,7 +35348,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
35337
35348
  return;
35338
35349
  }
35339
35350
  this._ensureAboutStyles();
35340
- var version = true ? "2.48.0" : 0;
35351
+ var version = true ? "2.48.2" : 0;
35341
35352
  var convId = this._getLastConversationId();
35342
35353
  var t = function t(k, fb) {
35343
35354
  try {