ttp-agent-sdk 2.48.0 → 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.
- package/dist/agent-widget.dev.js +431 -154
- package/dist/agent-widget.esm.js +1 -1
- package/dist/agent-widget.js +1 -1
- package/dist/demos/test-widget.html +72 -2
- package/dist/examples/test-widget.html +21 -0
- package/dist/index.html +19 -2
- package/examples/test-widget.html +69 -2
- package/package.json +2 -1
package/dist/agent-widget.dev.js
CHANGED
|
@@ -10748,7 +10748,7 @@ var ClientScriptManager = /*#__PURE__*/function () {
|
|
|
10748
10748
|
_ref2,
|
|
10749
10749
|
toolCallId,
|
|
10750
10750
|
toolName,
|
|
10751
|
-
|
|
10751
|
+
_ClientToolsRegistry$,
|
|
10752
10752
|
action,
|
|
10753
10753
|
args,
|
|
10754
10754
|
startedAt,
|
|
@@ -10765,7 +10765,7 @@ var ClientScriptManager = /*#__PURE__*/function () {
|
|
|
10765
10765
|
case 0:
|
|
10766
10766
|
conversationId = _args.length > 1 && _args[1] !== undefined ? _args[1] : null;
|
|
10767
10767
|
_ref2 = message || {}, toolCallId = _ref2.toolCallId, toolName = _ref2.toolName;
|
|
10768
|
-
|
|
10768
|
+
_ClientToolsRegistry$ = _ClientToolsRegistry_js__WEBPACK_IMPORTED_MODULE_0__["default"].resolveParameters(message), action = _ClientToolsRegistry$.action, args = _ClientToolsRegistry$.args;
|
|
10769
10769
|
startedAt = Date.now();
|
|
10770
10770
|
console.log("".concat(LOG).concat(this._tag(), " client_tool_call dispatch action=").concat(action, " toolCallId=").concat(toolCallId));
|
|
10771
10771
|
sendError = function sendError(error, errorCode) {
|
|
@@ -10888,11 +10888,11 @@ var ClientScriptManager = /*#__PURE__*/function () {
|
|
|
10888
10888
|
key: "handleRunPartnerScript",
|
|
10889
10889
|
value: (function () {
|
|
10890
10890
|
var _handleRunPartnerScript = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(message) {
|
|
10891
|
-
var
|
|
10891
|
+
var _ref3, requestId, partnerId, action, args, startedAt, result, elapsedMs, ok, serializedSize, sizeKB, limitKB, reason, _elapsedMs, _t2;
|
|
10892
10892
|
return _regenerator().w(function (_context2) {
|
|
10893
10893
|
while (1) switch (_context2.p = _context2.n) {
|
|
10894
10894
|
case 0:
|
|
10895
|
-
|
|
10895
|
+
_ref3 = message || {}, requestId = _ref3.requestId, partnerId = _ref3.partnerId, action = _ref3.action;
|
|
10896
10896
|
args = message && message.args || {};
|
|
10897
10897
|
if (requestId) {
|
|
10898
10898
|
_context2.n = 1;
|
|
@@ -11009,7 +11009,8 @@ var ClientScriptManager = /*#__PURE__*/function () {
|
|
|
11009
11009
|
}, {
|
|
11010
11010
|
key: "isClientToolsToolCall",
|
|
11011
11011
|
value: function isClientToolsToolCall(message) {
|
|
11012
|
-
|
|
11012
|
+
var parameters = _ClientToolsRegistry_js__WEBPACK_IMPORTED_MODULE_0__["default"].resolveParameters(message);
|
|
11013
|
+
return !!message && message.toolName === 'run_partner_script' && parameters.partner_id === CLIENT_TOOLS_PARTNER_ID;
|
|
11013
11014
|
}
|
|
11014
11015
|
}]);
|
|
11015
11016
|
}();
|
|
@@ -11127,6 +11128,20 @@ var ClientToolsRegistry = /*#__PURE__*/function () {
|
|
|
11127
11128
|
return Array.from(this.handlers.keys());
|
|
11128
11129
|
}
|
|
11129
11130
|
|
|
11131
|
+
/**
|
|
11132
|
+
* Resolve the object passed to a tool handler from a `client_tool_call` frame.
|
|
11133
|
+
*
|
|
11134
|
+
* The backend DTO (`ClientToolCallMessage`) serializes LLM args on
|
|
11135
|
+
* `parameters`. Handlers destructure that object (`params.selector`, …), so
|
|
11136
|
+
* `null` / a JSON string / an alternate field name would look like "params
|
|
11137
|
+
* aren't working". Always return a plain object.
|
|
11138
|
+
*
|
|
11139
|
+
* @param {Object} message
|
|
11140
|
+
* @returns {Object}
|
|
11141
|
+
*/
|
|
11142
|
+
}, {
|
|
11143
|
+
key: "handleToolCall",
|
|
11144
|
+
value: (
|
|
11130
11145
|
/**
|
|
11131
11146
|
* Handle incoming client_tool_call message from backend
|
|
11132
11147
|
* @param {Object} message - The tool call message
|
|
@@ -11134,19 +11149,19 @@ var ClientToolsRegistry = /*#__PURE__*/function () {
|
|
|
11134
11149
|
* @param {string} message.toolName - Name of the tool to execute
|
|
11135
11150
|
* @param {Object} message.parameters - Parameters for the tool
|
|
11136
11151
|
*/
|
|
11137
|
-
|
|
11138
|
-
key: "handleToolCall",
|
|
11139
|
-
value: (function () {
|
|
11152
|
+
function () {
|
|
11140
11153
|
var _handleToolCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(message) {
|
|
11141
|
-
var toolCallId, toolName, parameters, startTime, receiveTimestamp, handler, registeredTools, result, executionTimeMs, _error$message, _error$message2, _executionTimeMs, errorCode, _t;
|
|
11154
|
+
var _ref, toolCallId, toolName, parameters, startTime, receiveTimestamp, handler, registeredTools, result, executionTimeMs, _error$message, _error$message2, _executionTimeMs, errorCode, _t;
|
|
11142
11155
|
return _regenerator().w(function (_context) {
|
|
11143
11156
|
while (1) switch (_context.p = _context.n) {
|
|
11144
11157
|
case 0:
|
|
11145
|
-
|
|
11158
|
+
_ref = message || {}, toolCallId = _ref.toolCallId, toolName = _ref.toolName;
|
|
11159
|
+
parameters = ClientToolsRegistry.resolveParameters(message);
|
|
11146
11160
|
startTime = Date.now();
|
|
11147
11161
|
receiveTimestamp = new Date().toISOString();
|
|
11148
11162
|
console.log("\uD83D\uDD27 ClientTools: [".concat(receiveTimestamp, "] Received tool call '").concat(toolName, "' (id: ").concat(toolCallId, ")"));
|
|
11149
11163
|
console.log(" \uD83D\uDCCB Full message received:", JSON.stringify(message, null, 2));
|
|
11164
|
+
console.log(" \uD83D\uDCCB Resolved parameters:", parameters);
|
|
11150
11165
|
console.log(" \u23F1\uFE0F Start time: ".concat(startTime, "ms (").concat(new Date(startTime).toISOString(), ")"));
|
|
11151
11166
|
|
|
11152
11167
|
// Check if handler exists
|
|
@@ -11276,6 +11291,34 @@ var ClientToolsRegistry = /*#__PURE__*/function () {
|
|
|
11276
11291
|
value: function setSendMessage(sendMessage) {
|
|
11277
11292
|
this.sendMessage = sendMessage;
|
|
11278
11293
|
}
|
|
11294
|
+
}], [{
|
|
11295
|
+
key: "resolveParameters",
|
|
11296
|
+
value: function resolveParameters(message) {
|
|
11297
|
+
if (!message || _typeof(message) !== 'object') return {};
|
|
11298
|
+
var raw = message.parameters;
|
|
11299
|
+
if (raw == null) raw = message.params;
|
|
11300
|
+
if (raw == null) raw = message.args;
|
|
11301
|
+
if (raw == null) return {};
|
|
11302
|
+
if (typeof raw === 'string') {
|
|
11303
|
+
var trimmed = raw.trim();
|
|
11304
|
+
if (!trimmed) return {};
|
|
11305
|
+
try {
|
|
11306
|
+
var parsed = JSON.parse(trimmed);
|
|
11307
|
+
if (parsed !== null && _typeof(parsed) === 'object') return parsed;
|
|
11308
|
+
return {
|
|
11309
|
+
value: parsed
|
|
11310
|
+
};
|
|
11311
|
+
} catch (_unused2) {
|
|
11312
|
+
return {
|
|
11313
|
+
value: raw
|
|
11314
|
+
};
|
|
11315
|
+
}
|
|
11316
|
+
}
|
|
11317
|
+
if (_typeof(raw) === 'object') return raw;
|
|
11318
|
+
return {
|
|
11319
|
+
value: raw
|
|
11320
|
+
};
|
|
11321
|
+
}
|
|
11279
11322
|
}]);
|
|
11280
11323
|
}();
|
|
11281
11324
|
_defineProperty(ClientToolsRegistry, "MAX_RESULT_SIZE", 512000);
|
|
@@ -11384,6 +11427,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
11384
11427
|
/* harmony import */ var _EventEmitter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EventEmitter.js */ "./src/core/EventEmitter.js");
|
|
11385
11428
|
/* harmony import */ var _ClientToolsRegistry_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ClientToolsRegistry.js */ "./src/core/ClientToolsRegistry.js");
|
|
11386
11429
|
/* harmony import */ var _ClientScriptManager_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ClientScriptManager.js */ "./src/core/ClientScriptManager.js");
|
|
11430
|
+
/* harmony import */ var _helloFlavor_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helloFlavor.js */ "./src/core/helloFlavor.js");
|
|
11387
11431
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
11388
11432
|
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
11389
11433
|
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
@@ -11416,9 +11460,12 @@ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf
|
|
|
11416
11460
|
|
|
11417
11461
|
|
|
11418
11462
|
|
|
11463
|
+
|
|
11419
11464
|
var RECONNECT_DELAY_MS = 1000;
|
|
11420
11465
|
var MAX_RECONNECT_ATTEMPTS = 5;
|
|
11421
11466
|
var TEXT_CHAT_PATH = '/chat/text';
|
|
11467
|
+
/** Same interval as VoiceSDK — keeps proxies/LBs from dropping an idle text socket. */
|
|
11468
|
+
var KEEP_ALIVE_MS = 30000;
|
|
11422
11469
|
/** Production voice/text base (path swapped to /chat/text); matches VoiceSDK v2 default. */
|
|
11423
11470
|
var DEFAULT_WEBSOCKET_BASE_URL = 'wss://speech.talktopc.com/ws/conv';
|
|
11424
11471
|
var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
@@ -11440,6 +11487,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11440
11487
|
_this.connecting = false;
|
|
11441
11488
|
_this.reconnectAttempts = 0;
|
|
11442
11489
|
_this.intentionalClose = false;
|
|
11490
|
+
_this._keepAliveInterval = null;
|
|
11443
11491
|
_this.fullResponseBuffer = '';
|
|
11444
11492
|
_this.queue = [];
|
|
11445
11493
|
_this.inFlight = false;
|
|
@@ -11604,6 +11652,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11604
11652
|
_this2.connected = true;
|
|
11605
11653
|
_this2.reconnectAttempts = 0;
|
|
11606
11654
|
console.log('[TextChatSDK] Connected');
|
|
11655
|
+
_this2._startKeepAlive();
|
|
11607
11656
|
|
|
11608
11657
|
// Send hello immediately on connect (same fields as voice SDK v2 hello).
|
|
11609
11658
|
_this2.sendHelloMessage();
|
|
@@ -11719,13 +11768,16 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11719
11768
|
// Non-JSON or parse error; ignore
|
|
11720
11769
|
}
|
|
11721
11770
|
};
|
|
11771
|
+
|
|
11772
|
+
// Browser WebSocket.onerror is an Event, not an Error — emitting it would
|
|
11773
|
+
// render as the chat bubble "[object Event]". onclose handles recovery.
|
|
11722
11774
|
this.ws.onerror = function (e) {
|
|
11723
11775
|
console.error('[TextChatSDK] WebSocket error:', e);
|
|
11724
|
-
_this2.emit('error', e);
|
|
11725
11776
|
};
|
|
11726
11777
|
this.ws.onclose = function (event) {
|
|
11727
11778
|
_this2.connected = false;
|
|
11728
11779
|
_this2.connecting = false;
|
|
11780
|
+
_this2._stopKeepAlive();
|
|
11729
11781
|
console.log('[TextChatSDK] Disconnected, code:', event.code, 'reason:', event.reason);
|
|
11730
11782
|
|
|
11731
11783
|
// Domain whitelist error — don't reconnect
|
|
@@ -11963,9 +12015,10 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11963
12015
|
v: 2
|
|
11964
12016
|
};
|
|
11965
12017
|
|
|
11966
|
-
//
|
|
11967
|
-
|
|
11968
|
-
|
|
12018
|
+
// Partner fields only — UI-only keys like callView stay local (backend Flavor DTO rejects them)
|
|
12019
|
+
var wireFlavor = (0,_helloFlavor_js__WEBPACK_IMPORTED_MODULE_3__.flavorForHello)(this.config.flavor);
|
|
12020
|
+
if (wireFlavor) {
|
|
12021
|
+
helloMessage.flavor = wireFlavor;
|
|
11969
12022
|
}
|
|
11970
12023
|
|
|
11971
12024
|
// Variables (template variables injected into agent prompt)
|
|
@@ -11994,7 +12047,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
11994
12047
|
|
|
11995
12048
|
// SDK build time for debugging
|
|
11996
12049
|
if (true) {
|
|
11997
|
-
helloMessage.lastBuildTime = "2026-08-
|
|
12050
|
+
helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
|
|
11998
12051
|
}
|
|
11999
12052
|
try {
|
|
12000
12053
|
this.ws.send(JSON.stringify(helloMessage));
|
|
@@ -12023,6 +12076,27 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
12023
12076
|
};
|
|
12024
12077
|
}
|
|
12025
12078
|
}
|
|
12079
|
+
}, {
|
|
12080
|
+
key: "_startKeepAlive",
|
|
12081
|
+
value: function _startKeepAlive() {
|
|
12082
|
+
var _this4 = this;
|
|
12083
|
+
this._stopKeepAlive();
|
|
12084
|
+
this._keepAliveInterval = setInterval(function () {
|
|
12085
|
+
if (_this4.connected && _this4.ws && _this4.ws.readyState === WebSocket.OPEN) {
|
|
12086
|
+
_this4.sendRaw({
|
|
12087
|
+
t: 'ping'
|
|
12088
|
+
});
|
|
12089
|
+
}
|
|
12090
|
+
}, KEEP_ALIVE_MS);
|
|
12091
|
+
}
|
|
12092
|
+
}, {
|
|
12093
|
+
key: "_stopKeepAlive",
|
|
12094
|
+
value: function _stopKeepAlive() {
|
|
12095
|
+
if (this._keepAliveInterval) {
|
|
12096
|
+
clearInterval(this._keepAliveInterval);
|
|
12097
|
+
this._keepAliveInterval = null;
|
|
12098
|
+
}
|
|
12099
|
+
}
|
|
12026
12100
|
}, {
|
|
12027
12101
|
key: "persistConversationId",
|
|
12028
12102
|
value: function persistConversationId(conversationId) {
|
|
@@ -12055,6 +12129,7 @@ var TextChatSDK = /*#__PURE__*/function (_EventEmitter) {
|
|
|
12055
12129
|
this.queue = [];
|
|
12056
12130
|
this.inFlight = false;
|
|
12057
12131
|
this._currentTask = null;
|
|
12132
|
+
this._stopKeepAlive();
|
|
12058
12133
|
if (this.ws) {
|
|
12059
12134
|
try {
|
|
12060
12135
|
this.ws.close();
|
|
@@ -12622,6 +12697,35 @@ var webSocketSingleton = new WebSocketSingleton();
|
|
|
12622
12697
|
|
|
12623
12698
|
/***/ }),
|
|
12624
12699
|
|
|
12700
|
+
/***/ "./src/core/helloFlavor.js":
|
|
12701
|
+
/*!*********************************!*\
|
|
12702
|
+
!*** ./src/core/helloFlavor.js ***!
|
|
12703
|
+
\*********************************/
|
|
12704
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
12705
|
+
|
|
12706
|
+
"use strict";
|
|
12707
|
+
__webpack_require__.r(__webpack_exports__);
|
|
12708
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
12709
|
+
/* harmony export */ flavorForHello: () => (/* binding */ flavorForHello)
|
|
12710
|
+
/* harmony export */ });
|
|
12711
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
12712
|
+
/**
|
|
12713
|
+
* Flavor fields the conversation backend Flavor DTO understands.
|
|
12714
|
+
* UI-only keys (callView, …) stay on the widget config and must not go on hello.
|
|
12715
|
+
*/
|
|
12716
|
+
function flavorForHello(flavor) {
|
|
12717
|
+
if (!flavor || _typeof(flavor) !== 'object') return null;
|
|
12718
|
+
var out = {};
|
|
12719
|
+
if (flavor.type != null && String(flavor.type).trim() !== '') out.type = flavor.type;
|
|
12720
|
+
if (flavor.partnerId != null && String(flavor.partnerId).trim() !== '') out.partnerId = flavor.partnerId;
|
|
12721
|
+
if (flavor.shopifyDomain != null && String(flavor.shopifyDomain).trim() !== '') {
|
|
12722
|
+
out.shopifyDomain = flavor.shopifyDomain;
|
|
12723
|
+
}
|
|
12724
|
+
return Object.keys(out).length ? out : null;
|
|
12725
|
+
}
|
|
12726
|
+
|
|
12727
|
+
/***/ }),
|
|
12728
|
+
|
|
12625
12729
|
/***/ "./src/ecommerce/CartSummary.js":
|
|
12626
12730
|
/*!**************************************!*\
|
|
12627
12731
|
!*** ./src/ecommerce/CartSummary.js ***!
|
|
@@ -21253,8 +21357,8 @@ var VoiceSDK = _v2_VoiceSDK_js__WEBPACK_IMPORTED_MODULE_0__["default"];
|
|
|
21253
21357
|
|
|
21254
21358
|
|
|
21255
21359
|
// Version - injected at build time from package.json via webpack DefinePlugin
|
|
21256
|
-
var VERSION = "2.48.
|
|
21257
|
-
var BUILD_TIME = "2026-08-
|
|
21360
|
+
var VERSION = "2.48.2";
|
|
21361
|
+
var BUILD_TIME = "2026-08-20T14:41:57.957Z";
|
|
21258
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;');
|
|
21259
21363
|
|
|
21260
21364
|
// Named exports
|
|
@@ -25430,6 +25534,9 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
25430
25534
|
/* harmony import */ var _codecs_PCMUCodec_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./codecs/PCMUCodec.js */ "./src/v2/codecs/PCMUCodec.js");
|
|
25431
25535
|
/* harmony import */ var _codecs_PCMACodec_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./codecs/PCMACodec.js */ "./src/v2/codecs/PCMACodec.js");
|
|
25432
25536
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
25537
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
25538
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
25539
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
25433
25540
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
25434
25541
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
25435
25542
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
@@ -25505,6 +25612,15 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
25505
25612
|
_this.gainNode = null; // GainNode for volume/mute control
|
|
25506
25613
|
_this._audioContextPrimed = false; // Track if AudioContext has been primed with silent buffer
|
|
25507
25614
|
|
|
25615
|
+
// Last-hop AEC route (ElevenLabs WS pattern): play through a hidden
|
|
25616
|
+
// HTMLAudioElement instead of AudioContext.destination so Chrome/Safari
|
|
25617
|
+
// can use TTS as the echo-cancellation far-end. Scheduling / source.stop
|
|
25618
|
+
// still live on the AudioContext. Opt out with htmlAudioPlayback:false.
|
|
25619
|
+
_this._htmlAudioEl = null;
|
|
25620
|
+
_this._mediaStreamDest = null;
|
|
25621
|
+
_this._htmlAudioRouteActive = false;
|
|
25622
|
+
_this._htmlAudioPlayOk = false;
|
|
25623
|
+
|
|
25508
25624
|
// Track temporary listener in waitForAudioContextReady() for cleanup
|
|
25509
25625
|
_this._waitForReadyStateHandler = null;
|
|
25510
25626
|
_this.audioQueue = [];
|
|
@@ -25611,9 +25727,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
25611
25727
|
this.outputFormat = format;
|
|
25612
25728
|
console.log('✅ AudioPlayer v2: Format set:', format);
|
|
25613
25729
|
|
|
25614
|
-
//
|
|
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.
|
|
25615
25732
|
|
|
25616
|
-
if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate) {
|
|
25733
|
+
if (this.audioContext && oldSampleRate && oldSampleRate !== newSampleRate && !this._htmlHopNeedsHardwareRate()) {
|
|
25617
25734
|
console.warn('⚠️ AudioPlayer: Sample rate changed, recreating AudioContext');
|
|
25618
25735
|
console.warn(" Old: ".concat(oldSampleRate, "Hz \u2192 New: ").concat(newSampleRate, "Hz"));
|
|
25619
25736
|
|
|
@@ -25794,7 +25911,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
25794
25911
|
key: "prepareChunk",
|
|
25795
25912
|
value: (function () {
|
|
25796
25913
|
var _prepareChunk = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(pcmData) {
|
|
25797
|
-
var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate,
|
|
25914
|
+
var _this$outputFormat2, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, audioBuffer, actualDuration, _t;
|
|
25798
25915
|
return _regenerator().w(function (_context2) {
|
|
25799
25916
|
while (1) switch (_context2.p = _context2.n) {
|
|
25800
25917
|
case 0:
|
|
@@ -25843,27 +25960,21 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
25843
25960
|
|
|
25844
25961
|
// Create audio buffer with the ACTUAL sample rate of the audio data
|
|
25845
25962
|
audioDataSampleRate = ((_this$outputFormat2 = this.outputFormat) === null || _this$outputFormat2 === void 0 ? void 0 : _this$outputFormat2.sampleRate) || this.audioContext.sampleRate;
|
|
25846
|
-
contextSampleRate = this.audioContext.sampleRate;
|
|
25847
25963
|
audioBuffer = this.audioContext.createBuffer(1,
|
|
25848
25964
|
// mono
|
|
25849
25965
|
|
|
25850
25966
|
float32Array.length, audioDataSampleRate);
|
|
25851
25967
|
audioBuffer.getChannelData(0).set(float32Array);
|
|
25852
25968
|
|
|
25853
|
-
//
|
|
25854
|
-
|
|
25855
|
-
|
|
25856
|
-
actualDuration =
|
|
25857
|
-
if (contextSampleRate !== audioDataSampleRate) {
|
|
25858
|
-
actualDuration = sampleCount / contextSampleRate;
|
|
25859
|
-
}
|
|
25860
|
-
|
|
25861
|
-
// 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
|
|
25862
25973
|
return _context2.a(2, {
|
|
25863
25974
|
buffer: audioBuffer,
|
|
25864
25975
|
duration: actualDuration,
|
|
25865
25976
|
sampleRate: audioDataSampleRate,
|
|
25866
|
-
contextSampleRate:
|
|
25977
|
+
contextSampleRate: this.audioContext.sampleRate
|
|
25867
25978
|
});
|
|
25868
25979
|
case 4:
|
|
25869
25980
|
_context2.p = 4;
|
|
@@ -25920,6 +26031,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
25920
26031
|
return _context4.a(2);
|
|
25921
26032
|
case 2:
|
|
25922
26033
|
this.isSchedulingFrames = true;
|
|
26034
|
+
this._ensureHtmlAudioPlaying();
|
|
25923
26035
|
|
|
25924
26036
|
// Schedule multiple frames ahead to ensure continuous playback
|
|
25925
26037
|
// This prevents gaps when frames arrive slowly or there are timing delays
|
|
@@ -26219,7 +26331,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26219
26331
|
value: (function () {
|
|
26220
26332
|
var _processPcmQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
26221
26333
|
var _this5 = this;
|
|
26222
|
-
var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime,
|
|
26334
|
+
var _this$outputFormat3, _this$outputFormat4, pcmData, processedData, padded, int16Array, float32Array, NORMALIZATION, length, i, audioDataSampleRate, contextSampleRate, audioBuffer, source, currentTime, actualDuration, startTime, _t3;
|
|
26223
26335
|
return _regenerator().w(function (_context5) {
|
|
26224
26336
|
while (1) switch (_context5.p = _context5.n) {
|
|
26225
26337
|
case 0:
|
|
@@ -26306,16 +26418,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26306
26418
|
}
|
|
26307
26419
|
}
|
|
26308
26420
|
|
|
26309
|
-
//
|
|
26310
|
-
|
|
26311
|
-
|
|
26312
|
-
|
|
26313
|
-
|
|
26314
|
-
actualDuration = sampleCount / contextSampleRate;
|
|
26315
|
-
if (this.scheduledBuffers < 3) {
|
|
26316
|
-
console.log("\uD83D\uDD04 Resampling detected: ".concat(audioDataSampleRate, "Hz \u2192 ").concat(contextSampleRate, "Hz"));
|
|
26317
|
-
console.log(" Buffer duration: ".concat(chunkDuration.toFixed(4), "s, Calculated: ").concat(actualDuration.toFixed(4), "s"));
|
|
26318
|
-
}
|
|
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"));
|
|
26319
26426
|
}
|
|
26320
26427
|
|
|
26321
26428
|
// Schedule this chunk to start at nextStartTime
|
|
@@ -26779,6 +26886,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26779
26886
|
} catch (_) {/* ignore */}
|
|
26780
26887
|
this.gainNode = null;
|
|
26781
26888
|
}
|
|
26889
|
+
this._teardownHtmlAudioRoute();
|
|
26782
26890
|
if (this.audioContext === _sharedPlayerContext) {
|
|
26783
26891
|
_sharedPlayerContext = null;
|
|
26784
26892
|
_sharedPlayerSampleRate = null;
|
|
@@ -26921,6 +27029,148 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26921
27029
|
}
|
|
26922
27030
|
return _waitForAudioContextReadyImpl;
|
|
26923
27031
|
}()
|
|
27032
|
+
}, {
|
|
27033
|
+
key: "wantsHtmlAudioPlayback",
|
|
27034
|
+
value: function wantsHtmlAudioPlayback() {
|
|
27035
|
+
return this.config.htmlAudioPlayback !== false;
|
|
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
|
+
}
|
|
27060
|
+
}, {
|
|
27061
|
+
key: "getHtmlAudioPlaybackInfo",
|
|
27062
|
+
value: function getHtmlAudioPlaybackInfo() {
|
|
27063
|
+
return {
|
|
27064
|
+
htmlAudioPlayback: this.wantsHtmlAudioPlayback(),
|
|
27065
|
+
htmlAudioRouteActive: this._htmlAudioRouteActive,
|
|
27066
|
+
htmlAudioPlayOk: this._htmlAudioPlayOk
|
|
27067
|
+
};
|
|
27068
|
+
}
|
|
27069
|
+
|
|
27070
|
+
/**
|
|
27071
|
+
* Last hop: GainNode → MediaStreamDestination → hidden <audio>.
|
|
27072
|
+
* Falls back to AudioContext.destination if the HTML route cannot start.
|
|
27073
|
+
*/
|
|
27074
|
+
}, {
|
|
27075
|
+
key: "_connectGainToOutput",
|
|
27076
|
+
value: function _connectGainToOutput() {
|
|
27077
|
+
if (!this.gainNode || !this.audioContext) {
|
|
27078
|
+
return;
|
|
27079
|
+
}
|
|
27080
|
+
try {
|
|
27081
|
+
this.gainNode.disconnect();
|
|
27082
|
+
} catch (_) {/* ignore */}
|
|
27083
|
+
if (this.wantsHtmlAudioPlayback() && this._ensureHtmlAudioRoute()) {
|
|
27084
|
+
this.gainNode.connect(this._mediaStreamDest);
|
|
27085
|
+
return;
|
|
27086
|
+
}
|
|
27087
|
+
this.gainNode.connect(this.audioContext.destination);
|
|
27088
|
+
this._htmlAudioRouteActive = false;
|
|
27089
|
+
}
|
|
27090
|
+
}, {
|
|
27091
|
+
key: "_ensureHtmlAudioRoute",
|
|
27092
|
+
value: function _ensureHtmlAudioRoute() {
|
|
27093
|
+
if (this._htmlAudioRouteActive && this._htmlAudioEl && this._mediaStreamDest) {
|
|
27094
|
+
this._ensureHtmlAudioPlaying();
|
|
27095
|
+
return true;
|
|
27096
|
+
}
|
|
27097
|
+
if (!this.audioContext || typeof this.audioContext.createMediaStreamDestination !== 'function') {
|
|
27098
|
+
console.warn('⚠️ AudioPlayer: MediaStreamDestination unavailable — using AudioContext.destination');
|
|
27099
|
+
return false;
|
|
27100
|
+
}
|
|
27101
|
+
try {
|
|
27102
|
+
this._mediaStreamDest = this.audioContext.createMediaStreamDestination();
|
|
27103
|
+
var el = document.createElement('audio');
|
|
27104
|
+
el.setAttribute('playsinline', '');
|
|
27105
|
+
el.setAttribute('webkit-playsinline', '');
|
|
27106
|
+
el.autoplay = true;
|
|
27107
|
+
el.controls = false;
|
|
27108
|
+
el.preload = 'auto';
|
|
27109
|
+
el.playbackRate = 1;
|
|
27110
|
+
el.style.display = 'none';
|
|
27111
|
+
el.srcObject = this._mediaStreamDest.stream;
|
|
27112
|
+
document.body.appendChild(el);
|
|
27113
|
+
this._htmlAudioEl = el;
|
|
27114
|
+
this._htmlAudioRouteActive = true;
|
|
27115
|
+
this._ensureHtmlAudioPlaying();
|
|
27116
|
+
console.log('🔊 AudioPlayer: Playback last-hop is HTMLAudioElement (AEC far-end route)');
|
|
27117
|
+
return true;
|
|
27118
|
+
} catch (e) {
|
|
27119
|
+
console.warn('⚠️ AudioPlayer: HTML audio route failed, falling back to destination:', e);
|
|
27120
|
+
this._teardownHtmlAudioRoute();
|
|
27121
|
+
return false;
|
|
27122
|
+
}
|
|
27123
|
+
}
|
|
27124
|
+
}, {
|
|
27125
|
+
key: "_ensureHtmlAudioPlaying",
|
|
27126
|
+
value: function _ensureHtmlAudioPlaying() {
|
|
27127
|
+
var _this7 = this;
|
|
27128
|
+
var el = this._htmlAudioEl;
|
|
27129
|
+
if (!el) return;
|
|
27130
|
+
if (!el.paused && this._htmlAudioPlayOk) return;
|
|
27131
|
+
var playResult = el.play();
|
|
27132
|
+
if (playResult && typeof playResult.then === 'function') {
|
|
27133
|
+
playResult.then(function () {
|
|
27134
|
+
_this7._htmlAudioPlayOk = true;
|
|
27135
|
+
}).catch(function (err) {
|
|
27136
|
+
if (_this7._htmlAudioPlayOk || !el.paused) {
|
|
27137
|
+
return;
|
|
27138
|
+
}
|
|
27139
|
+
console.warn('⚠️ AudioPlayer: HTMLAudioElement.play() rejected — falling back to destination:', err);
|
|
27140
|
+
_this7._fallbackToDestination('play_rejected');
|
|
27141
|
+
});
|
|
27142
|
+
}
|
|
27143
|
+
}
|
|
27144
|
+
}, {
|
|
27145
|
+
key: "_fallbackToDestination",
|
|
27146
|
+
value: function _fallbackToDestination(reason) {
|
|
27147
|
+
if (!this.gainNode || !this.audioContext) return;
|
|
27148
|
+
try {
|
|
27149
|
+
this.gainNode.disconnect();
|
|
27150
|
+
} catch (_) {/* ignore */}
|
|
27151
|
+
this._teardownHtmlAudioRoute();
|
|
27152
|
+
this.gainNode.connect(this.audioContext.destination);
|
|
27153
|
+
console.warn("\u26A0\uFE0F AudioPlayer: Fell back to AudioContext.destination (".concat(reason, ")"));
|
|
27154
|
+
}
|
|
27155
|
+
}, {
|
|
27156
|
+
key: "_teardownHtmlAudioRoute",
|
|
27157
|
+
value: function _teardownHtmlAudioRoute() {
|
|
27158
|
+
if (this._htmlAudioEl) {
|
|
27159
|
+
try {
|
|
27160
|
+
this._htmlAudioEl.pause();
|
|
27161
|
+
} catch (_) {/* ignore */}
|
|
27162
|
+
try {
|
|
27163
|
+
this._htmlAudioEl.srcObject = null;
|
|
27164
|
+
} catch (_) {/* ignore */}
|
|
27165
|
+
if (this._htmlAudioEl.parentNode) {
|
|
27166
|
+
this._htmlAudioEl.parentNode.removeChild(this._htmlAudioEl);
|
|
27167
|
+
}
|
|
27168
|
+
this._htmlAudioEl = null;
|
|
27169
|
+
}
|
|
27170
|
+
this._mediaStreamDest = null;
|
|
27171
|
+
this._htmlAudioRouteActive = false;
|
|
27172
|
+
}
|
|
27173
|
+
|
|
26924
27174
|
/**
|
|
26925
27175
|
* Initialize audio context with correct sample rate
|
|
26926
27176
|
*/
|
|
@@ -26928,16 +27178,16 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26928
27178
|
key: "initializeAudioContext",
|
|
26929
27179
|
value: (function () {
|
|
26930
27180
|
var _initializeAudioContext = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
|
|
26931
|
-
var
|
|
26932
|
-
|
|
26933
|
-
_this$outputFormat6;
|
|
26934
|
-
var desiredSampleRate, currentSampleRate, canReuseShared, setupAfterResume, _t4;
|
|
27181
|
+
var _this8 = this;
|
|
27182
|
+
var ttsSampleRate, useHardwareRate, desiredSampleRate, contextFits, canReuseShared, setupAfterResume, ctxOpts, _t4;
|
|
26935
27183
|
return _regenerator().w(function (_context8) {
|
|
26936
27184
|
while (1) switch (_context8.p = _context8.n) {
|
|
26937
27185
|
case 0:
|
|
26938
|
-
|
|
26939
|
-
|
|
26940
|
-
|
|
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)) {
|
|
26941
27191
|
console.log("\u2139\uFE0F AudioPlayer: Backend requested ".concat(desiredSampleRate, "Hz, but browser may resample"));
|
|
26942
27192
|
console.log(" Consider requesting 24000Hz, 44100Hz, or 48000Hz from backend to reduce resampling");
|
|
26943
27193
|
}
|
|
@@ -26945,8 +27195,10 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26945
27195
|
_sharedPlayerContext = null;
|
|
26946
27196
|
_sharedPlayerSampleRate = null;
|
|
26947
27197
|
}
|
|
26948
|
-
|
|
26949
|
-
|
|
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
|
|
26950
27202
|
if (!this.audioContext) {
|
|
26951
27203
|
_context8.n = 3;
|
|
26952
27204
|
break;
|
|
@@ -26959,43 +27211,41 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
26959
27211
|
_context8.n = 3;
|
|
26960
27212
|
break;
|
|
26961
27213
|
case 1:
|
|
26962
|
-
|
|
26963
|
-
if (!(Math.abs(currentSampleRate - desiredSampleRate) > 100)) {
|
|
27214
|
+
if (!contextFits(this.audioContext.sampleRate)) {
|
|
26964
27215
|
_context8.n = 2;
|
|
26965
27216
|
break;
|
|
26966
27217
|
}
|
|
26967
|
-
|
|
27218
|
+
this._ensureHtmlAudioPlaying();
|
|
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..."));
|
|
26968
27222
|
this.stopImmediate();
|
|
26969
27223
|
this._cleanupAudioContext();
|
|
26970
|
-
_context8.n = 3;
|
|
26971
|
-
break;
|
|
26972
|
-
case 2:
|
|
26973
|
-
return _context8.a(2);
|
|
26974
27224
|
case 3:
|
|
26975
27225
|
// iOS FIX: Reuse shared AudioContext if available and compatible.
|
|
26976
27226
|
// iOS WebKit doesn't release audio hardware synchronously on AudioContext.close(),
|
|
26977
27227
|
// causing newly created AudioContexts to fail silently.
|
|
26978
|
-
canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' &&
|
|
27228
|
+
canReuseShared = _sharedPlayerContext && _sharedPlayerContext.state !== 'closed' && contextFits(_sharedPlayerContext.sampleRate);
|
|
26979
27229
|
if (!canReuseShared) {
|
|
26980
27230
|
_context8.n = 8;
|
|
26981
27231
|
break;
|
|
26982
27232
|
}
|
|
26983
|
-
console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(
|
|
27233
|
+
console.log("\u267B\uFE0F AudioPlayer: Reusing shared AudioContext at ".concat(_sharedPlayerContext.sampleRate, "Hz (iOS-safe)"));
|
|
26984
27234
|
this.audioContext = _sharedPlayerContext;
|
|
26985
27235
|
setupAfterResume = function setupAfterResume() {
|
|
26986
|
-
|
|
26987
|
-
if (
|
|
27236
|
+
_this8.setupAudioContextStateMonitoring();
|
|
27237
|
+
if (_this8.gainNode) {
|
|
26988
27238
|
try {
|
|
26989
|
-
|
|
27239
|
+
_this8.gainNode.disconnect();
|
|
26990
27240
|
} catch (e) {
|
|
26991
27241
|
console.warn('⚠️ AudioPlayer: Error disconnecting old GainNode:', e);
|
|
26992
27242
|
}
|
|
26993
27243
|
}
|
|
26994
|
-
|
|
26995
|
-
|
|
26996
|
-
|
|
26997
|
-
if (!
|
|
26998
|
-
|
|
27244
|
+
_this8.gainNode = _this8.audioContext.createGain();
|
|
27245
|
+
_this8.gainNode.gain.value = 1.0;
|
|
27246
|
+
_this8._connectGainToOutput();
|
|
27247
|
+
if (!_this8._audioContextPrimed) {
|
|
27248
|
+
_this8._primeAudioContext();
|
|
26999
27249
|
}
|
|
27000
27250
|
};
|
|
27001
27251
|
if (!(this.audioContext.state === 'suspended')) {
|
|
@@ -27016,7 +27266,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27016
27266
|
setupAfterResume();
|
|
27017
27267
|
return _context8.a(2);
|
|
27018
27268
|
case 8:
|
|
27019
|
-
console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext
|
|
27269
|
+
console.log("\uD83C\uDFB5 AudioPlayer: Creating AudioContext (tts=".concat(ttsSampleRate, "Hz, htmlHop=").concat(useHardwareRate, ", requested=").concat(desiredSampleRate || 'hardware default', ")"));
|
|
27020
27270
|
|
|
27021
27271
|
// Close old shared context if sample rate changed
|
|
27022
27272
|
if (_sharedPlayerContext && _sharedPlayerContext.state !== 'closed') {
|
|
@@ -27028,29 +27278,27 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27028
27278
|
}
|
|
27029
27279
|
}
|
|
27030
27280
|
try {
|
|
27031
|
-
|
|
27032
|
-
sampleRate: desiredSampleRate,
|
|
27281
|
+
ctxOpts = {
|
|
27033
27282
|
latencyHint: 'playback'
|
|
27034
|
-
}
|
|
27283
|
+
};
|
|
27284
|
+
if (desiredSampleRate) {
|
|
27285
|
+
ctxOpts.sampleRate = desiredSampleRate;
|
|
27286
|
+
}
|
|
27287
|
+
this.audioContext = new (window.AudioContext || window.webkitAudioContext)(ctxOpts);
|
|
27035
27288
|
|
|
27036
27289
|
// Store as shared context
|
|
27037
27290
|
_sharedPlayerContext = this.audioContext;
|
|
27038
|
-
_sharedPlayerSampleRate =
|
|
27039
|
-
console.log("\u2705 AudioContext created at ".concat(this.audioContext.sampleRate, "Hz (
|
|
27040
|
-
if (
|
|
27041
|
-
console.
|
|
27042
|
-
|
|
27043
|
-
console.
|
|
27044
|
-
console.error(" This WILL cause audio distortion/noise!");
|
|
27045
|
-
console.error(" Solution: Backend should send ".concat(this.audioContext.sampleRate, "Hz audio instead"));
|
|
27046
|
-
} else if (this.audioContext.sampleRate !== desiredSampleRate) {
|
|
27047
|
-
console.warn("\u26A0\uFE0F Browser adjusted sample rate: ".concat(desiredSampleRate, "Hz \u2192 ").concat(this.audioContext.sampleRate, "Hz"));
|
|
27048
|
-
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"));
|
|
27049
27297
|
}
|
|
27050
27298
|
this.setupAudioContextStateMonitoring();
|
|
27051
27299
|
this.gainNode = this.audioContext.createGain();
|
|
27052
27300
|
this.gainNode.gain.value = 1.0;
|
|
27053
|
-
this.
|
|
27301
|
+
this._connectGainToOutput();
|
|
27054
27302
|
console.log('✅ AudioPlayer: GainNode created for volume control');
|
|
27055
27303
|
this._primeAudioContext();
|
|
27056
27304
|
} catch (error) {
|
|
@@ -27062,7 +27310,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27062
27310
|
this.setupAudioContextStateMonitoring();
|
|
27063
27311
|
this.gainNode = this.audioContext.createGain();
|
|
27064
27312
|
this.gainNode.gain.value = 1.0;
|
|
27065
|
-
this.
|
|
27313
|
+
this._connectGainToOutput();
|
|
27066
27314
|
console.log('✅ AudioPlayer: GainNode created for volume control (fallback)');
|
|
27067
27315
|
this._primeAudioContext();
|
|
27068
27316
|
}
|
|
@@ -27100,8 +27348,11 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27100
27348
|
silentBuffer = this.audioContext.createBuffer(1, sampleRate * 0.15, sampleRate);
|
|
27101
27349
|
source = this.audioContext.createBufferSource();
|
|
27102
27350
|
source.buffer = silentBuffer;
|
|
27103
|
-
|
|
27351
|
+
// Prime through the same last hop as real TTS so iOS treats the hidden
|
|
27352
|
+
// <audio> as "playing media" (ElevenLabs maybePrimeIosPlayback).
|
|
27353
|
+
source.connect(this.gainNode || this.audioContext.destination);
|
|
27104
27354
|
source.start();
|
|
27355
|
+
this._ensureHtmlAudioPlaying();
|
|
27105
27356
|
_context9.n = 2;
|
|
27106
27357
|
return new Promise(function (resolve) {
|
|
27107
27358
|
return setTimeout(resolve, 150);
|
|
@@ -27135,7 +27386,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27135
27386
|
value: function _cleanupAudioContext() {
|
|
27136
27387
|
console.log('[TTP AudioPlayer] 🧹 Cleaning up AudioContext (iOS-safe: keeping shared context alive)');
|
|
27137
27388
|
|
|
27138
|
-
// Disconnect and cleanup gainNode
|
|
27389
|
+
// Disconnect and cleanup gainNode + HTML audio last-hop
|
|
27139
27390
|
if (this.gainNode) {
|
|
27140
27391
|
try {
|
|
27141
27392
|
this.gainNode.disconnect();
|
|
@@ -27144,6 +27395,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27144
27395
|
}
|
|
27145
27396
|
this.gainNode = null;
|
|
27146
27397
|
}
|
|
27398
|
+
this._teardownHtmlAudioRoute();
|
|
27147
27399
|
|
|
27148
27400
|
// Remove state change listener first
|
|
27149
27401
|
if (this._audioContextStateChangeHandler && this.audioContext) {
|
|
@@ -27184,7 +27436,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27184
27436
|
* Handles mic permission grants, tab switching, browser suspension, etc.
|
|
27185
27437
|
*/
|
|
27186
27438
|
function setupAudioContextStateMonitoring() {
|
|
27187
|
-
var
|
|
27439
|
+
var _this9 = this;
|
|
27188
27440
|
if (!this.audioContext) {
|
|
27189
27441
|
return;
|
|
27190
27442
|
}
|
|
@@ -27197,35 +27449,38 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27197
27449
|
// Create handler that references this.audioContext dynamically
|
|
27198
27450
|
this._audioContextStateChangeHandler = function () {
|
|
27199
27451
|
// Null check required because audioContext may be cleaned up while handler is queued
|
|
27200
|
-
if (!
|
|
27452
|
+
if (!_this9.audioContext) {
|
|
27201
27453
|
console.warn('⚠️ AudioPlayer: State change handler fired but AudioContext is null');
|
|
27202
27454
|
return;
|
|
27203
27455
|
}
|
|
27204
|
-
console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(
|
|
27205
|
-
if (
|
|
27456
|
+
console.log("\uD83C\uDFB5 AudioPlayer: AudioContext state changed to: ".concat(_this9.audioContext.state));
|
|
27457
|
+
if (_this9.audioContext.state === 'running') {
|
|
27458
|
+
_this9._ensureHtmlAudioPlaying();
|
|
27459
|
+
}
|
|
27460
|
+
if (_this9.audioContext.state === 'suspended' && _this9.isPlaying) {
|
|
27206
27461
|
// AudioContext was suspended during playback (tab switch, mic permission, etc.)
|
|
27207
27462
|
console.warn('⚠️ AudioPlayer: AudioContext suspended during playback');
|
|
27208
27463
|
// Note: Playback will pause automatically, but we should handle queue processing
|
|
27209
27464
|
// The state change will be handled when we try to process next frame
|
|
27210
|
-
} else if (
|
|
27465
|
+
} else if (_this9.audioContext.state === 'running' && !_this9.isPlaying && (_this9.audioQueue.length > 0 || _this9.pcmChunkQueue.length > 0 || _this9.preparedBuffer.length > 0)) {
|
|
27211
27466
|
// AudioContext resumed and we have queued frames
|
|
27212
27467
|
// This handles: mic permission grant, tab switching back, browser resume, etc.
|
|
27213
27468
|
console.log('✅ AudioPlayer: AudioContext resumed - resuming queue processing');
|
|
27214
27469
|
|
|
27215
27470
|
// Resume queue processing if we have frames
|
|
27216
|
-
if (
|
|
27471
|
+
if (_this9.audioQueue.length > 0 && !_this9.isProcessingQueue) {
|
|
27217
27472
|
setTimeout(function () {
|
|
27218
|
-
return
|
|
27473
|
+
return _this9.processQueue();
|
|
27219
27474
|
}, 50);
|
|
27220
27475
|
}
|
|
27221
|
-
if (
|
|
27476
|
+
if (_this9.pcmChunkQueue.length > 0 && !_this9.isProcessingPcmQueue) {
|
|
27222
27477
|
setTimeout(function () {
|
|
27223
|
-
return
|
|
27478
|
+
return _this9.processPcmQueue();
|
|
27224
27479
|
}, 50);
|
|
27225
27480
|
}
|
|
27226
|
-
if (
|
|
27481
|
+
if (_this9.preparedBuffer.length > 0 && !_this9.isSchedulingFrames) {
|
|
27227
27482
|
setTimeout(function () {
|
|
27228
|
-
return
|
|
27483
|
+
return _this9.scheduleFrames();
|
|
27229
27484
|
}, 50);
|
|
27230
27485
|
}
|
|
27231
27486
|
}
|
|
@@ -27244,7 +27499,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27244
27499
|
key: "processQueue",
|
|
27245
27500
|
value: (function () {
|
|
27246
27501
|
var _processQueue = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
|
|
27247
|
-
var
|
|
27502
|
+
var _this0 = this;
|
|
27248
27503
|
var audioBlob, wasFirstPlay, audioContext, arrayBuffer, audioBuffer, shouldEmitStart, source, _t6;
|
|
27249
27504
|
return _regenerator().w(function (_context0) {
|
|
27250
27505
|
while (1) switch (_context0.p = _context0.n) {
|
|
@@ -27263,6 +27518,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27263
27518
|
return _context0.a(2);
|
|
27264
27519
|
case 2:
|
|
27265
27520
|
this.isProcessingQueue = true;
|
|
27521
|
+
this._ensureHtmlAudioPlaying();
|
|
27266
27522
|
audioBlob = this.audioQueue.shift();
|
|
27267
27523
|
if (audioBlob) {
|
|
27268
27524
|
_context0.n = 3;
|
|
@@ -27303,22 +27559,22 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27303
27559
|
// Handle end
|
|
27304
27560
|
|
|
27305
27561
|
source.onended = function () {
|
|
27306
|
-
|
|
27307
|
-
|
|
27562
|
+
_this0.currentSource = null;
|
|
27563
|
+
_this0.isProcessingQueue = false;
|
|
27308
27564
|
|
|
27309
27565
|
// Process next chunk
|
|
27310
27566
|
|
|
27311
|
-
if (
|
|
27567
|
+
if (_this0.audioQueue.length > 0) {
|
|
27312
27568
|
setTimeout(function () {
|
|
27313
|
-
return
|
|
27569
|
+
return _this0.processQueue();
|
|
27314
27570
|
}, 50);
|
|
27315
27571
|
} else {
|
|
27316
27572
|
// No more chunks - stop after delay
|
|
27317
27573
|
|
|
27318
27574
|
setTimeout(function () {
|
|
27319
|
-
if (
|
|
27320
|
-
|
|
27321
|
-
|
|
27575
|
+
if (_this0.audioQueue.length === 0 && !_this0.currentSource) {
|
|
27576
|
+
_this0.isPlaying = false;
|
|
27577
|
+
_this0.emit('playbackStopped');
|
|
27322
27578
|
}
|
|
27323
27579
|
}, 100);
|
|
27324
27580
|
}
|
|
@@ -27341,7 +27597,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27341
27597
|
if (this.audioQueue.length > 0) {
|
|
27342
27598
|
this.isProcessingQueue = false;
|
|
27343
27599
|
setTimeout(function () {
|
|
27344
|
-
return
|
|
27600
|
+
return _this0.processQueue();
|
|
27345
27601
|
}, 100);
|
|
27346
27602
|
} else {
|
|
27347
27603
|
this.isPlaying = false;
|
|
@@ -27564,7 +27820,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27564
27820
|
}, {
|
|
27565
27821
|
key: "markNewSentence",
|
|
27566
27822
|
value: function markNewSentence(text, synced, segmentId) {
|
|
27567
|
-
var
|
|
27823
|
+
var _this1 = this;
|
|
27568
27824
|
var wasStopped = this._isStopped;
|
|
27569
27825
|
var isCurrentlyPlaying = this.isPlaying || this.scheduledSources.size > 0;
|
|
27570
27826
|
|
|
@@ -27623,34 +27879,34 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27623
27879
|
var sentenceText = text; // Capture for timeout callback
|
|
27624
27880
|
this._emptySentenceTimeout = setTimeout(function () {
|
|
27625
27881
|
// Check if this sentence still has no chunks after timeout
|
|
27626
|
-
if (
|
|
27882
|
+
if (_this1.pendingSentenceText === sentenceText && _this1.scheduledBuffers === 0 && _this1.preparedBuffer.length === 0 && _this1.pcmChunkQueue.length === 0 && !_this1._isStopped) {
|
|
27627
27883
|
console.warn("\u26A0\uFE0F AudioPlayer: Empty sentence detected after 5s timeout - no chunks received for: \"".concat(sentenceText.substring(0, 40), "...\""));
|
|
27628
27884
|
// If this empty sentence carried a segment id, report it done (nothing was heard) and
|
|
27629
27885
|
// adopt it as current so the coarse stop below matches the backend's last-sent id.
|
|
27630
|
-
if (
|
|
27631
|
-
var emptySegId =
|
|
27632
|
-
|
|
27633
|
-
|
|
27634
|
-
|
|
27886
|
+
if (_this1.pendingSegmentId != null) {
|
|
27887
|
+
var emptySegId = _this1.pendingSegmentId;
|
|
27888
|
+
_this1.currentSegmentId = emptySegId;
|
|
27889
|
+
_this1.pendingSegmentId = null;
|
|
27890
|
+
_this1.emit('segmentDone', {
|
|
27635
27891
|
segmentId: emptySegId,
|
|
27636
27892
|
status: 'finished',
|
|
27637
27893
|
playedMs: 0
|
|
27638
27894
|
});
|
|
27639
27895
|
}
|
|
27640
27896
|
// Clear pending sentence to unblock next sentence
|
|
27641
|
-
if (
|
|
27642
|
-
|
|
27897
|
+
if (_this1.pendingSentenceText === sentenceText) {
|
|
27898
|
+
_this1.pendingSentenceText = null;
|
|
27643
27899
|
}
|
|
27644
27900
|
// Emit playbackStopped to allow next sentence to start
|
|
27645
27901
|
// Only if we're not currently playing (to avoid interrupting real playback)
|
|
27646
|
-
if (!
|
|
27902
|
+
if (!_this1.isPlaying && _this1.scheduledSources.size === 0) {
|
|
27647
27903
|
console.log('🛑 AudioPlayer: Emitting playbackStopped for empty sentence timeout');
|
|
27648
|
-
|
|
27649
|
-
segmentId:
|
|
27904
|
+
_this1.emit('playbackStopped', {
|
|
27905
|
+
segmentId: _this1.currentSegmentId
|
|
27650
27906
|
});
|
|
27651
27907
|
}
|
|
27652
27908
|
}
|
|
27653
|
-
|
|
27909
|
+
_this1._emptySentenceTimeout = null;
|
|
27654
27910
|
}, 5000); // 5 second timeout - adjust based on expected chunk arrival rate
|
|
27655
27911
|
}
|
|
27656
27912
|
|
|
@@ -27660,14 +27916,14 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27660
27916
|
}, {
|
|
27661
27917
|
key: "startTranscriptChecker",
|
|
27662
27918
|
value: function startTranscriptChecker() {
|
|
27663
|
-
var
|
|
27919
|
+
var _this10 = this;
|
|
27664
27920
|
if (this.isCheckingTranscripts) return;
|
|
27665
27921
|
this.isCheckingTranscripts = true;
|
|
27666
27922
|
console.log('📝 AudioPlayer: Transcript checker started');
|
|
27667
27923
|
var _checkLoop = function checkLoop() {
|
|
27668
|
-
if (!
|
|
27669
|
-
var currentTime =
|
|
27670
|
-
var _iterator2 = _createForOfIteratorHelper(
|
|
27924
|
+
if (!_this10.isCheckingTranscripts || !_this10.audioContext) return;
|
|
27925
|
+
var currentTime = _this10.audioContext.currentTime;
|
|
27926
|
+
var _iterator2 = _createForOfIteratorHelper(_this10.sentenceTimings),
|
|
27671
27927
|
_step2;
|
|
27672
27928
|
try {
|
|
27673
27929
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -27681,13 +27937,13 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27681
27937
|
eventData.synced = _timing.synced;
|
|
27682
27938
|
}
|
|
27683
27939
|
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, ")"));
|
|
27684
|
-
|
|
27940
|
+
_this10.emit('transcriptDisplay', eventData);
|
|
27685
27941
|
}
|
|
27686
27942
|
// Per-segment natural finish: this segment's audio window has fully elapsed.
|
|
27687
27943
|
if (!_timing.doneReported && _timing.endTime != null && currentTime >= _timing.endTime) {
|
|
27688
27944
|
_timing.doneReported = true;
|
|
27689
27945
|
var _playedMs = Math.round((_timing.endTime - _timing.startTime) * 1000);
|
|
27690
|
-
|
|
27946
|
+
_this10.emit('segmentDone', {
|
|
27691
27947
|
segmentId: _timing.segmentId,
|
|
27692
27948
|
status: 'finished',
|
|
27693
27949
|
playedMs: _playedMs
|
|
@@ -27699,12 +27955,12 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27699
27955
|
} finally {
|
|
27700
27956
|
_iterator2.f();
|
|
27701
27957
|
}
|
|
27702
|
-
if (
|
|
27958
|
+
if (_this10.isPlaying || _this10.scheduledBuffers > 0) {
|
|
27703
27959
|
requestAnimationFrame(_checkLoop);
|
|
27704
27960
|
} else {
|
|
27705
27961
|
// Playback drained naturally — flush any segment whose finish tick we may have missed
|
|
27706
27962
|
// (the last buffer's onended can flip isPlaying=false before this loop's next tick).
|
|
27707
|
-
var _iterator3 = _createForOfIteratorHelper(
|
|
27963
|
+
var _iterator3 = _createForOfIteratorHelper(_this10.sentenceTimings),
|
|
27708
27964
|
_step3;
|
|
27709
27965
|
try {
|
|
27710
27966
|
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
@@ -27713,7 +27969,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27713
27969
|
timing.doneReported = true;
|
|
27714
27970
|
var end = timing.endTime != null ? timing.endTime : timing.startTime;
|
|
27715
27971
|
var playedMs = Math.round((end - timing.startTime) * 1000);
|
|
27716
|
-
|
|
27972
|
+
_this10.emit('segmentDone', {
|
|
27717
27973
|
segmentId: timing.segmentId,
|
|
27718
27974
|
status: 'finished',
|
|
27719
27975
|
playedMs: playedMs
|
|
@@ -27725,7 +27981,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27725
27981
|
} finally {
|
|
27726
27982
|
_iterator3.f();
|
|
27727
27983
|
}
|
|
27728
|
-
|
|
27984
|
+
_this10.isCheckingTranscripts = false;
|
|
27729
27985
|
console.log('📝 AudioPlayer: Transcript checker stopped');
|
|
27730
27986
|
}
|
|
27731
27987
|
};
|
|
@@ -27831,7 +28087,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27831
28087
|
}, {
|
|
27832
28088
|
key: "getStatus",
|
|
27833
28089
|
value: function getStatus() {
|
|
27834
|
-
return {
|
|
28090
|
+
return _objectSpread({
|
|
27835
28091
|
isPlaying: this.isPlaying,
|
|
27836
28092
|
isProcessingQueue: this.isProcessingQueue,
|
|
27837
28093
|
queueLength: this.audioQueue.length,
|
|
@@ -27840,7 +28096,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
|
|
|
27840
28096
|
scheduledBuffers: this.scheduledBuffers,
|
|
27841
28097
|
preparedBufferLength: this.preparedBuffer.length,
|
|
27842
28098
|
scheduledSourcesCount: this.scheduledSources.size
|
|
27843
|
-
};
|
|
28099
|
+
}, this.getHtmlAudioPlaybackInfo());
|
|
27844
28100
|
}
|
|
27845
28101
|
|
|
27846
28102
|
/**
|
|
@@ -27888,8 +28144,9 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
27888
28144
|
/* harmony import */ var _utils_AudioFormatConverter_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/AudioFormatConverter.js */ "./src/v2/utils/AudioFormatConverter.js");
|
|
27889
28145
|
/* harmony import */ var _core_ClientToolsRegistry_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../core/ClientToolsRegistry.js */ "./src/core/ClientToolsRegistry.js");
|
|
27890
28146
|
/* harmony import */ var _core_ClientScriptManager_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../core/ClientScriptManager.js */ "./src/core/ClientScriptManager.js");
|
|
27891
|
-
/* harmony import */ var
|
|
27892
|
-
/* harmony import */ var
|
|
28147
|
+
/* harmony import */ var _core_helloFlavor_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../core/helloFlavor.js */ "./src/core/helloFlavor.js");
|
|
28148
|
+
/* harmony import */ var _utils_screenshot_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/screenshot.js */ "./src/utils/screenshot.js");
|
|
28149
|
+
/* harmony import */ var _utils_visual_tools_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/visual-tools.js */ "./src/utils/visual-tools.js");
|
|
27893
28150
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
27894
28151
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
27895
28152
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
@@ -27924,6 +28181,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
27924
28181
|
|
|
27925
28182
|
|
|
27926
28183
|
|
|
28184
|
+
|
|
27927
28185
|
/**
|
|
27928
28186
|
|
|
27929
28187
|
* VoiceSDK v2 - Multi-codec speech-to-speech SDK
|
|
@@ -28021,6 +28279,9 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28021
28279
|
// Audio constraints for getUserMedia (optional)
|
|
28022
28280
|
// If not provided, defaults will be used: echoCancellation: true, noiseSuppression: true, autoGainControl: true
|
|
28023
28281
|
audioConstraints: config.audioConstraints || null,
|
|
28282
|
+
// Last-hop TTS playback via hidden <audio> (AEC far-end). Default on.
|
|
28283
|
+
// Set false to fall back to AudioContext.destination (old path).
|
|
28284
|
+
htmlAudioPlayback: config.htmlAudioPlayback !== false,
|
|
28024
28285
|
// Protocol version
|
|
28025
28286
|
|
|
28026
28287
|
protocolVersion: config.protocolVersion || 2,
|
|
@@ -28142,7 +28403,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28142
28403
|
key: "_registerBuiltInTools",
|
|
28143
28404
|
value: function _registerBuiltInTools() {
|
|
28144
28405
|
try {
|
|
28145
|
-
(0,
|
|
28406
|
+
(0,_utils_visual_tools_js__WEBPACK_IMPORTED_MODULE_8__.registerVisualTools)(this.clientToolsRegistry);
|
|
28146
28407
|
} catch (error) {
|
|
28147
28408
|
console.error('❌ VoiceSDK: Error registering built-in tools:', error);
|
|
28148
28409
|
console.error(' Error details:', error.message, error.stack);
|
|
@@ -28880,7 +29141,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28880
29141
|
// iOS in-app webviews lack "Safari" in the UA (real Safari always has it).
|
|
28881
29142
|
var webview = isAndroid && (/\bwv\b/.test(ua) || /Version\/[\d.]+.*Chrome/.test(ua)) || isIos && !/Safari/i.test(ua) || false;
|
|
28882
29143
|
var env = {
|
|
28883
|
-
sdkVersion: true ? "2.48.
|
|
29144
|
+
sdkVersion: true ? "2.48.2" : 0,
|
|
28884
29145
|
ua: ua,
|
|
28885
29146
|
platform: (uaData === null || uaData === void 0 ? void 0 : uaData.platform) || navigator.platform || '',
|
|
28886
29147
|
mobile: (_uaData$mobile = uaData === null || uaData === void 0 ? void 0 : uaData.mobile) !== null && _uaData$mobile !== void 0 ? _uaData$mobile : isAndroid || isIos,
|
|
@@ -28895,7 +29156,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28895
29156
|
} catch (e) {
|
|
28896
29157
|
console.warn('⚠️ VoiceSDK v2: Failed to build client env:', e);
|
|
28897
29158
|
return {
|
|
28898
|
-
sdkVersion: true ? "2.48.
|
|
29159
|
+
sdkVersion: true ? "2.48.2" : 0
|
|
28899
29160
|
};
|
|
28900
29161
|
}
|
|
28901
29162
|
}
|
|
@@ -28911,11 +29172,11 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28911
29172
|
key: "_sendClientAudioInfo",
|
|
28912
29173
|
value: function _sendClientAudioInfo() {
|
|
28913
29174
|
try {
|
|
28914
|
-
var _this$audioRecorder, _this$audioRecorder$g, _s$echoCancellation, _s$noiseSuppression, _s$autoGainControl, _s$voiceIsolation, _s$sampleRate, _s$channelCount, _this$audioRecorder2, _this$audioPlayer, _this$audioRecorder3;
|
|
29175
|
+
var _this$audioRecorder, _this$audioRecorder$g, _s$echoCancellation, _s$noiseSuppression, _s$autoGainControl, _s$voiceIsolation, _s$sampleRate, _s$channelCount, _this$audioRecorder2, _this$audioPlayer, _this$audioRecorder3, _this$audioPlayer2, _this$audioPlayer2$ge;
|
|
28915
29176
|
var track = (_this$audioRecorder = this.audioRecorder) === null || _this$audioRecorder === void 0 || (_this$audioRecorder = _this$audioRecorder.mediaStream) === null || _this$audioRecorder === void 0 || (_this$audioRecorder$g = _this$audioRecorder.getAudioTracks) === null || _this$audioRecorder$g === void 0 ? void 0 : _this$audioRecorder$g.call(_this$audioRecorder)[0];
|
|
28916
29177
|
if (!track) return;
|
|
28917
29178
|
var s = track.getSettings ? track.getSettings() : {};
|
|
28918
|
-
var audio = {
|
|
29179
|
+
var audio = _objectSpread({
|
|
28919
29180
|
aec: (_s$echoCancellation = s.echoCancellation) !== null && _s$echoCancellation !== void 0 ? _s$echoCancellation : null,
|
|
28920
29181
|
ns: (_s$noiseSuppression = s.noiseSuppression) !== null && _s$noiseSuppression !== void 0 ? _s$noiseSuppression : null,
|
|
28921
29182
|
agc: (_s$autoGainControl = s.autoGainControl) !== null && _s$autoGainControl !== void 0 ? _s$autoGainControl : null,
|
|
@@ -28926,7 +29187,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28926
29187
|
captureCtxRate: ((_this$audioRecorder2 = this.audioRecorder) === null || _this$audioRecorder2 === void 0 || (_this$audioRecorder2 = _this$audioRecorder2.audioContext) === null || _this$audioRecorder2 === void 0 ? void 0 : _this$audioRecorder2.sampleRate) || null,
|
|
28927
29188
|
playbackCtxRate: ((_this$audioPlayer = this.audioPlayer) === null || _this$audioPlayer === void 0 || (_this$audioPlayer = _this$audioPlayer.audioContext) === null || _this$audioPlayer === void 0 ? void 0 : _this$audioPlayer.sampleRate) || null,
|
|
28928
29189
|
constraintsFallback: ((_this$audioRecorder3 = this.audioRecorder) === null || _this$audioRecorder3 === void 0 || (_this$audioRecorder3 = _this$audioRecorder3.mediaStream) === null || _this$audioRecorder3 === void 0 ? void 0 : _this$audioRecorder3._ttpConstraintsFallback) === true
|
|
28929
|
-
};
|
|
29190
|
+
}, ((_this$audioPlayer2 = this.audioPlayer) === null || _this$audioPlayer2 === void 0 || (_this$audioPlayer2$ge = _this$audioPlayer2.getHtmlAudioPlaybackInfo) === null || _this$audioPlayer2$ge === void 0 ? void 0 : _this$audioPlayer2$ge.call(_this$audioPlayer2)) || {});
|
|
28930
29191
|
this.sendMessage({
|
|
28931
29192
|
t: 'client_audio_info',
|
|
28932
29193
|
audio: audio
|
|
@@ -28940,7 +29201,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
28940
29201
|
key: "sendHelloMessage",
|
|
28941
29202
|
value: function () {
|
|
28942
29203
|
var _sendHelloMessage = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
28943
|
-
var inputFormat, requestedOutputFormat, inputError, outputError, helloMessage;
|
|
29204
|
+
var inputFormat, requestedOutputFormat, inputError, outputError, helloMessage, wireFlavor;
|
|
28944
29205
|
return _regenerator().w(function (_context2) {
|
|
28945
29206
|
while (1) switch (_context2.n) {
|
|
28946
29207
|
case 0:
|
|
@@ -29029,14 +29290,15 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
29029
29290
|
console.log('⚠️ VoiceSDK v2: Variables NOT included - condition failed');
|
|
29030
29291
|
}
|
|
29031
29292
|
|
|
29032
|
-
//
|
|
29033
|
-
|
|
29034
|
-
|
|
29293
|
+
// Partner fields only — UI-only keys like callView stay local (backend Flavor DTO rejects them)
|
|
29294
|
+
wireFlavor = (0,_core_helloFlavor_js__WEBPACK_IMPORTED_MODULE_6__.flavorForHello)(this.config.flavor);
|
|
29295
|
+
if (wireFlavor) {
|
|
29296
|
+
helloMessage.flavor = wireFlavor;
|
|
29035
29297
|
}
|
|
29036
29298
|
|
|
29037
29299
|
// Include SDK build time for debugging
|
|
29038
29300
|
if (true) {
|
|
29039
|
-
helloMessage.lastBuildTime = "2026-08-
|
|
29301
|
+
helloMessage.lastBuildTime = "2026-08-20T14:41:57.957Z";
|
|
29040
29302
|
}
|
|
29041
29303
|
|
|
29042
29304
|
// Client environment (device/browser/webview) for backend logs + Langfuse metadata
|
|
@@ -29280,7 +29542,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
29280
29542
|
case 'get_page_context':
|
|
29281
29543
|
// Handle get_page_context request from backend
|
|
29282
29544
|
console.log('📖 [VISUAL ASSISTANT] Backend requested page context');
|
|
29283
|
-
(0,
|
|
29545
|
+
(0,_utils_visual_tools_js__WEBPACK_IMPORTED_MODULE_8__.extractPageContext)().then(function (pageContext) {
|
|
29284
29546
|
// Use existing DOM scanner
|
|
29285
29547
|
_this6.sendMessage({
|
|
29286
29548
|
t: 'page_context',
|
|
@@ -29301,7 +29563,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
|
|
|
29301
29563
|
console.log('📸 [VISUAL ASSISTANT] Backend requested screenshot');
|
|
29302
29564
|
try {
|
|
29303
29565
|
// Use existing screenshot capture function
|
|
29304
|
-
(0,
|
|
29566
|
+
(0,_utils_screenshot_js__WEBPACK_IMPORTED_MODULE_7__.captureScreenshot)().then(function (screenshot) {
|
|
29305
29567
|
_this6.sendMessage({
|
|
29306
29568
|
t: 'screenshot',
|
|
29307
29569
|
screenshot: {
|
|
@@ -32579,6 +32841,7 @@ var AgentSDK = /*#__PURE__*/function () {
|
|
|
32579
32841
|
outputBitDepth: this.config.outputBitDepth || 16,
|
|
32580
32842
|
// Default: 16-bit
|
|
32581
32843
|
flavor: this.config.flavor || null,
|
|
32844
|
+
htmlAudioPlayback: this.config.htmlAudioPlayback !== false,
|
|
32582
32845
|
// Shared client-tool handler map (set by TTPChatWidget so voice + text SDKs
|
|
32583
32846
|
// both look up handlers in the same registration site).
|
|
32584
32847
|
sharedToolHandlers: this.config.sharedToolHandlers || null,
|
|
@@ -34573,7 +34836,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
34573
34836
|
agentTextColor: ((_userConfig$messages8 = userConfig.messages) === null || _userConfig$messages8 === void 0 ? void 0 : _userConfig$messages8.agentTextColor) || ((_userConfig$messages9 = userConfig.messages) === null || _userConfig$messages9 === void 0 ? void 0 : _userConfig$messages9.textColor) || '#1F2937',
|
|
34574
34837
|
userAvatarIcon: ((_userConfig$messages0 = userConfig.messages) === null || _userConfig$messages0 === void 0 ? void 0 : _userConfig$messages0.userAvatarIcon) || '👤',
|
|
34575
34838
|
agentAvatarIcon: ((_userConfig$messages1 = userConfig.messages) === null || _userConfig$messages1 === void 0 ? void 0 : _userConfig$messages1.agentAvatarIcon) || '🤖',
|
|
34576
|
-
fontSize: ((_userConfig$messages10 = userConfig.messages) === null || _userConfig$messages10 === void 0 ? void 0 : _userConfig$messages10.fontSize) || '
|
|
34839
|
+
fontSize: ((_userConfig$messages10 = userConfig.messages) === null || _userConfig$messages10 === void 0 ? void 0 : _userConfig$messages10.fontSize) || '15px',
|
|
34577
34840
|
borderRadius: ((_userConfig$messages11 = userConfig.messages) === null || _userConfig$messages11 === void 0 ? void 0 : _userConfig$messages11.borderRadius) || 16
|
|
34578
34841
|
}, userConfig.messages),
|
|
34579
34842
|
// Animation Configuration
|
|
@@ -34662,7 +34925,10 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
34662
34925
|
if (error && (error.message === 'DOMAIN_NOT_WHITELISTED' || error.message && error.message.includes('Domain not whitelisted'))) {
|
|
34663
34926
|
return; // Already handled by domainError event
|
|
34664
34927
|
}
|
|
34665
|
-
|
|
34928
|
+
// WS onerror is a browser Event (no .message) — do not paint "[object Event]"
|
|
34929
|
+
var text = typeof error === 'string' ? error : error && error.message;
|
|
34930
|
+
if (!text) return;
|
|
34931
|
+
_this5.textInterface.showError(text);
|
|
34666
34932
|
_this5.textInterface.stopStreamingState();
|
|
34667
34933
|
});
|
|
34668
34934
|
this.sdk.on('chunk', function (chunk) {
|
|
@@ -35082,7 +35348,7 @@ var TTPChatWidget = /*#__PURE__*/function () {
|
|
|
35082
35348
|
return;
|
|
35083
35349
|
}
|
|
35084
35350
|
this._ensureAboutStyles();
|
|
35085
|
-
var version = true ? "2.48.
|
|
35351
|
+
var version = true ? "2.48.2" : 0;
|
|
35086
35352
|
var convId = this._getLastConversationId();
|
|
35087
35353
|
var t = function t(k, fb) {
|
|
35088
35354
|
try {
|
|
@@ -37533,6 +37799,16 @@ var MESSAGE_COLLAPSE_THRESHOLD = 353;
|
|
|
37533
37799
|
|
|
37534
37800
|
/** How often a streaming agent bubble is re-rendered from its markdown buffer (ms). */
|
|
37535
37801
|
var STREAM_RENDER_INTERVAL_MS = 40;
|
|
37802
|
+
|
|
37803
|
+
/**
|
|
37804
|
+
* The time + delivery checks sit absolutely positioned in the bubble's bottom
|
|
37805
|
+
* corner, so the bubble reserves a physical gutter wide enough that the last
|
|
37806
|
+
* line of text can never run underneath them. GUTTER must stay comfortably
|
|
37807
|
+
* wider than INSET plus the rendered metadata ("23:59 ✓✓" — 24h time is the
|
|
37808
|
+
* widest case); `test/text-interface.test.mjs` asserts the two stay in step.
|
|
37809
|
+
*/
|
|
37810
|
+
var MESSAGE_META_INSET_PX = 14;
|
|
37811
|
+
var MESSAGE_META_GUTTER_PX = 68;
|
|
37536
37812
|
function collapseMessageText(text) {
|
|
37537
37813
|
if (text.length <= MESSAGE_COLLAPSE_THRESHOLD) return text;
|
|
37538
37814
|
return "".concat(text.slice(0, MESSAGE_COLLAPSE_THRESHOLD).trimEnd(), "\u2026");
|
|
@@ -37649,7 +37925,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37649
37925
|
var inputFontSize = this.config.inputFontSize || ((_this$config$panel0 = this.config.panel) === null || _this$config$panel0 === void 0 ? void 0 : _this$config$panel0.inputFontSize) || '16px';
|
|
37650
37926
|
var inputBorderRadius = this.config.inputBorderRadius || ((_this$config$panel1 = this.config.panel) === null || _this$config$panel1 === void 0 ? void 0 : _this$config$panel1.inputBorderRadius) || 20;
|
|
37651
37927
|
var inputPadding = this.config.inputPadding || ((_this$config$panel10 = this.config.panel) === null || _this$config$panel10 === void 0 ? void 0 : _this$config$panel10.inputPadding) || '9px 12px';
|
|
37652
|
-
var messageFontSize = messages.fontSize || '
|
|
37928
|
+
var messageFontSize = messages.fontSize || '15px';
|
|
37653
37929
|
var panelLight;
|
|
37654
37930
|
var topBarBg;
|
|
37655
37931
|
var topBarBorder;
|
|
@@ -37769,7 +38045,7 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
37769
38045
|
|
|
37770
38046
|
// Add !important to display rules when not using Shadow DOM (to override theme CSS)
|
|
37771
38047
|
var important = this.config.useShadowDOM === false ? ' !important' : '';
|
|
37772
|
-
return "\n .text-interface-top-bar {\n flex-shrink: 0".concat(important, ";\n padding: 12px 14px").concat(important, ";\n border-bottom: 1px solid ").concat(topBarBorder).concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: flex-start").concat(important, ";\n gap: 10px").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface-agent-heading {\n display: flex").concat(important, ";\n flex-direction: row").concat(important, ";\n align-items: center").concat(important, ";\n gap: 9px").concat(important, ";\n min-width: 0").concat(important, ";\n flex: 1").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .text-interface-agent-avatar {\n width: 36px").concat(important, ";\n height: 36px").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex: 0 0 36px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: ").concat(useVoiceTheme ? avatarAgentBg : "linear-gradient(135deg, ".concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")")).concat(important, ";\n border: none").concat(important, ";\n box-shadow: none").concat(important, ";\n }\n .text-interface-agent-initial { color: #fff").concat(important, "; font-size: 14px").concat(important, "; font-weight: 500").concat(important, "; line-height: 1").concat(important, "; }\n .text-interface-agent-copy {\n display: flex").concat(important, ";\n flex-direction: column").concat(important, ";\n align-items: flex-start").concat(important, ";\n gap: 2px").concat(important, ";\n min-width: 0").concat(important, ";\n }\n .text-interface-agent-name {\n color: #f0eff8").concat(important, ";\n font-size: 14px").concat(important, ";\n font-weight: 500").concat(important, ";\n line-height: 1.15").concat(important, ";\n overflow: hidden").concat(important, ";\n text-overflow: ellipsis").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-agent-status {\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 6px").concat(important, ";\n color: rgba(255,255,255,0.7)").concat(important, ";\n font-size: 10px").concat(important, ";\n }\n .text-interface-agent-status > span {\n width: 7px").concat(important, ";\n height: 7px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: #4ade80").concat(important, ";\n box-shadow: 0 0 10px rgba(74,222,128,0.75)").concat(important, ";\n }\n .text-interface-top-actions { display: flex").concat(important, "; align-items: center").concat(important, "; gap: 4px").concat(important, "; margin-inline-start: auto").concat(important, "; }\n .text-interface-close-btn:hover,\n .text-interface-home-btn:hover,\n .text-interface-footer .ttp-info-btn:hover {\n background: rgba(255,255,255,0.22)").concat(important, ";\n color: #ffffff").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.26), 0 4px 14px rgba(0,0,0,0.22)").concat(important, ";\n }\n .text-interface-close-btn,\n .text-interface-home-btn,\n .text-interface-footer .ttp-info-btn {\n width: 32px").concat(important, ";\n height: 32px").concat(important, ";\n display: grid").concat(important, ";\n place-items: center").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n border: 1px solid rgba(255,255,255,0.14)").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n cursor: pointer").concat(important, ";\n font-family: inherit").concat(important, ";\n transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.14)").concat(important, ";\n }\n .text-interface-home-btn svg,\n .text-interface-close-btn svg,\n .text-interface-footer .ttp-info-btn svg { width: 18px").concat(important, "; height: 18px").concat(important, "; fill: none").concat(important, "; stroke: currentColor").concat(important, "; stroke-width: 1.9").concat(important, "; stroke-linecap: round").concat(important, "; stroke-linejoin: round").concat(important, "; }\n .text-interface-home-btn svg { fill: none").concat(important, "; stroke: currentColor").concat(important, "; width: 20px").concat(important, "; height: 20px").concat(important, "; stroke-width: 1.8").concat(important, "; }\n .input-container .text-interface-home-btn {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n flex-shrink: 0").concat(important, ";\n }\n /* Messages container using new classes */\n #messagesContainer { \n flex: 1").concat(important, "; \n overflow-y: auto").concat(important, "; \n overflow-x: hidden").concat(important, "; \n padding: 20px").concat(important, "; \n background: ").concat(messagesAreaBg).concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n gap: 16px").concat(important, "; \n min-height: 0").concat(important, "; \n }\n .empty-state { \n flex: 1").concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n gap: 12px").concat(important, "; \n color: ").concat(emptyMuted).concat(important, "; \n text-align: center").concat(important, "; \n padding: 20px").concat(important, "; \n }\n .empty-state-icon { font-size: 52px").concat(important, "; opacity: 0.3").concat(important, "; }\n .empty-state-title { font-size: 22px").concat(important, "; font-weight: 700").concat(important, "; color: ").concat(emptyTitle).concat(important, "; }\n .empty-state-text { font-size: 15px").concat(important, "; max-width: 300px").concat(important, "; line-height: 1.45").concat(important, "; }\n .empty-state-icon {\n width: 48px").concat(important, "; height: 48px").concat(important, "; border-radius: 16px").concat(important, ";\n display: grid").concat(important, "; place-items: center").concat(important, "; color: rgba(230,225,255,0.9)").concat(important, ";\n background: rgba(255,255,255,0.1)").concat(important, ";\n border: 1px solid rgba(225,219,255,0.18)").concat(important, ";\n }\n .empty-state-icon svg { width: 24px").concat(important, "; height: 24px").concat(important, "; }\n\n .text-interface { \n display: none").concat(important, "; \n flex: 1").concat(important, "; \n flex-direction: column").concat(important, "; \n min-height: 0").concat(important, "; \n overflow: hidden").concat(important, "; \n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface.active { display: flex").concat(important, "; }\n \n .message { \n display: flex").concat(important, "; \n flex-direction: column").concat(important, ";\n gap: 4px").concat(important, ";\n padding: 4px 0").concat(important, "; \n width: 100%").concat(important, ";\n max-width: 100%").concat(important, "; \n align-items: stretch").concat(important, ";\n }\n .message-bubble { \n position: relative").concat(important, ";\n padding: 8px 62px 8px 11px").concat(important, ";\n padding-right: 62px").concat(important, ";\n border-radius: 12px").concat(important, ";\n max-width: min(72%, 420px)").concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n line-height: 1.36").concat(important, ";\n word-wrap: break-word").concat(important, "; \n box-shadow: ").concat(useVoiceTheme ? 'inset 0 1px 0 rgba(255,255,255,0.36), inset 0 -1px 0 rgba(5, 3, 26, 0.18), 0 8px 20px rgba(4, 3, 22, 0.24)' : 'none').concat(important, ";\n }\n .message-bubble[dir=\"rtl\"] { text-align: right").concat(important, "; direction: rtl").concat(important, "; }\n .message-bubble[dir=\"ltr\"] { text-align: left").concat(important, "; direction: ltr").concat(important, "; }\n .message-bubble::before {\n content: ''").concat(important, ";\n position: absolute").concat(important, ";\n top: 1px").concat(important, ";\n right: 1px").concat(important, ";\n left: 1px").concat(important, ";\n height: 48%").concat(important, ";\n border-radius: 11px 11px 8px 8px").concat(important, ";\n background: linear-gradient(180deg, rgba(255,255,255,0.19), rgba(255,255,255,0))").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-bubble { \n background: ").concat(userBubbleBg).concat(important, "; \n color: ").concat(userBubbleTextColor).concat(important, "; \n border-top-right-radius: 4px").concat(important, ";\n }\n .message.agent .message-bubble {\n background: ").concat(agentBubbleBg).concat(important, ";\n color: ").concat(agentBubbleTextColor).concat(important, ";\n border: ").concat(agentBubbleBorder).concat(important, ";\n border-top-left-radius: 4px").concat(important, ";\n }\n\n /* ---------------------------------------------------------------\n Rendered markdown inside the agent bubble.\n Everything is scoped to .message-bubble so host-page styles can't\n reach in and the user bubble (plain text) is untouched.\n Logical properties (padding-inline-start, border-inline-start) keep\n the layout correct in RTL locales such as Hebrew.\n ---------------------------------------------------------------- */\n .message-bubble.md, .message-bubble .md-seg { line-height: 1.55").concat(important, "; }\n .message-bubble .md-seg { display: block").concat(important, "; }\n\n .message-bubble p {\n margin: 0 0 10px").concat(important, ";\n padding: 0").concat(important, ";\n }\n /* Deliberately gated on .md / .md-seg rather than a bare\n \".message-bubble > *\": the VOICE live-transcript row reuses the\n .message-bubble class in this same shadow root, and its children\n (.live-badge, .ttp-cursor) are not ours to restyle. */\n .message-bubble.md > *:last-child,\n .message-bubble .md-seg:last-child > *:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble.md > *:first-child,\n .message-bubble .md-seg:first-child > *:first-child { margin-top: 0").concat(important, "; }\n\n .message-bubble .md-h {\n margin: 16px 0 7px").concat(important, ";\n padding: 0").concat(important, ";\n font-weight: 700").concat(important, ";\n line-height: 1.3").concat(important, ";\n color: inherit").concat(important, ";\n }\n .message-bubble .md-h1 { font-size: 1.18em").concat(important, "; }\n .message-bubble .md-h2 { font-size: 1.09em").concat(important, "; }\n .message-bubble .md-h3 { font-size: 1.02em").concat(important, "; }\n .message-bubble .md-h4,\n .message-bubble .md-h5,\n .message-bubble .md-h6 {\n font-size: 0.95em").concat(important, ";\n letter-spacing: 0.02em").concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n\n /* Logical properties only \u2014 a physical padding-left/border-left after\n these would resolve to the same property and silently win in LTR. */\n .message-bubble ul, .message-bubble ol {\n margin: 8px 0 11px").concat(important, ";\n padding-inline-start: 1.45em").concat(important, ";\n list-style-position: outside").concat(important, ";\n }\n .message-bubble ul { list-style-type: disc").concat(important, "; }\n .message-bubble ol { list-style-type: decimal").concat(important, "; }\n .message-bubble ul ul { list-style-type: circle").concat(important, "; }\n .message-bubble li {\n margin: 0 0 5px").concat(important, ";\n padding: 0").concat(important, ";\n line-height: 1.5").concat(important, ";\n }\n .message-bubble li:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble li::marker { color: ").concat(mdAccent).concat(important, "; }\n .message-bubble li > ul, .message-bubble li > ol { margin: 5px 0 2px").concat(important, "; }\n .message-bubble li > p { margin: 0 0 5px").concat(important, "; }\n\n .message-bubble strong, .message-bubble b { font-weight: 700").concat(important, "; }\n .message-bubble em, .message-bubble i { font-style: italic").concat(important, "; }\n .message-bubble del { text-decoration: line-through").concat(important, "; opacity: 0.7").concat(important, "; }\n\n .message-bubble a {\n color: ").concat(mdLink).concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n word-break: break-word").concat(important, ";\n }\n .message-bubble a:hover { opacity: 0.82").concat(important, "; }\n\n .message-bubble code {\n font-family: ").concat(mdMono).concat(important, ";\n font-size: 0.88em").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 5px").concat(important, ";\n padding: 1px 5px").concat(important, ";\n white-space: break-spaces").concat(important, ";\n word-break: break-word").concat(important, ";\n direction: ltr").concat(important, ";\n unicode-bidi: embed").concat(important, ";\n }\n .message-bubble pre {\n margin: 10px 0 11px").concat(important, ";\n padding: 10px 12px").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 10px").concat(important, ";\n overflow-x: auto").concat(important, ";\n direction: ltr").concat(important, ";\n text-align: left").concat(important, ";\n }\n .message-bubble pre code {\n background: none").concat(important, ";\n border: none").concat(important, ";\n border-radius: 0").concat(important, ";\n padding: 0").concat(important, ";\n font-size: 0.85em").concat(important, ";\n line-height: 1.5").concat(important, ";\n white-space: pre").concat(important, ";\n word-break: normal").concat(important, ";\n }\n\n .message-bubble blockquote {\n margin: 10px 0").concat(important, ";\n padding-block: 2px").concat(important, ";\n padding-inline-start: 12px").concat(important, ";\n padding-inline-end: 0").concat(important, ";\n border-inline-start: 3px solid ").concat(mdAccent).concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n .message-bubble blockquote > *:last-child { margin-bottom: 0").concat(important, "; }\n\n .message-bubble hr {\n border: none").concat(important, ";\n border-top: 1px solid ").concat(mdRule).concat(important, ";\n height: 0").concat(important, ";\n margin: 13px 0").concat(important, ";\n }\n\n .message-bubble .md-table-wrap {\n margin: 10px 0 11px").concat(important, ";\n overflow-x: auto").concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 9px").concat(important, ";\n }\n .message-bubble table {\n border-collapse: collapse").concat(important, ";\n width: 100%").concat(important, ";\n font-size: 0.93em").concat(important, ";\n }\n .message-bubble th, .message-bubble td {\n padding: 7px 11px").concat(important, ";\n text-align: start").concat(important, ";\n border-bottom: 1px solid ").concat(mdBorder).concat(important, ";\n vertical-align: top").concat(important, ";\n }\n .message-bubble thead th {\n background: ").concat(mdSubtleBg).concat(important, ";\n font-weight: 700").concat(important, ";\n }\n .message-bubble tbody tr:nth-child(even) { background: ").concat(mdSubtlerBg).concat(important, "; }\n .message-bubble tbody tr:last-child td { border-bottom: none").concat(important, "; }\n\n .message-bubble .md-img {\n display: block").concat(important, ";\n max-width: 100%").concat(important, ";\n height: auto").concat(important, ";\n border-radius: 8px").concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n\n .message.user { \n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.agent {\n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.user .message-bubble {\n margin-left: auto").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .message.agent .message-bubble {\n margin-left: 0").concat(important, ";\n margin-right: auto").concat(important, ";\n }\n .message-meta {\n position: absolute").concat(important, ";\n right: 11px").concat(important, ";\n bottom: 8px").concat(important, ";\n z-index: 2").concat(important, ";\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 5px").concat(important, ";\n margin: 0").concat(important, ";\n color: rgba(255,255,255,0.55)").concat(important, ";\n font-size: 9px").concat(important, ";\n line-height: 1").concat(important, ";\n direction: ltr").concat(important, ";\n white-space: nowrap").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-meta {\n color: rgba(255,255,255,0.74)").concat(important, ";\n }\n .message-content { position: relative").concat(important, "; z-index: 1").concat(important, "; display: inline").concat(important, "; overflow-wrap: anywhere").concat(important, "; word-break: break-word").concat(important, "; direction: inherit").concat(important, "; }\n .message-meta-spacer { display: inline-block").concat(important, "; width: 0").concat(important, "; height: 1px").concat(important, "; }\n .message-delivery-checks { color: rgba(255,255,255,0.92)").concat(important, "; font-weight: 700").concat(important, "; letter-spacing: -2px").concat(important, "; }\n .message-expand-button {\n position: relative").concat(important, ";\n z-index: 3").concat(important, ";\n margin: 0 4px").concat(important, ";\n padding: 0").concat(important, ";\n border: 0").concat(important, ";\n background: transparent").concat(important, ";\n color: #c4b5fd").concat(important, ";\n font: inherit").concat(important, ";\n font-size: 0.78em").concat(important, ";\n font-weight: 600").concat(important, ";\n line-height: inherit").concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n cursor: pointer").concat(important, ";\n }\n .message-expand-button:hover { color: #ede9fe").concat(important, "; }\n .message-avatar { \n width: ").concat(avatarSize).concat(important, "; \n height: ").concat(avatarSize).concat(important, "; \n min-width: ").concat(avatarSize).concat(important, "; \n border-radius: 50%").concat(important, "; \n display: flex").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n flex-shrink: 0").concat(important, "; \n color: inherit").concat(important, "; \n font-size: ").concat(useVoiceTheme ? '14' : '20', "px").concat(important, "; \n line-height: 1").concat(important, "; \n background: transparent").concat(important, "; \n border: none").concat(important, "; \n box-sizing: border-box").concat(important, "; \n }\n .message-avatar.user { background: ").concat(avatarUserBg).concat(important, "; color: ").concat(avatarUserColor).concat(important, "; }\n .message-avatar.agent { background: ").concat(avatarAgentBg).concat(important, "; }\n \n .message.system {\n background: ").concat(messages.systemBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n .message.error {\n background: ").concat(messages.errorBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n \n .input-container {\n display: flex").concat(important, ";\n gap: 8px").concat(important, ";\n padding: 12px 16px").concat(important, ";\n background: ").concat(inputContainerBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n align-items: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n flex-direction: row").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer {\n position: relative").concat(important, ";\n flex-shrink: 0").concat(important, ";\n min-height: 28px").concat(important, ";\n padding: 4px 12px").concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n display: flex").concat(important, ";\n justify-content: center").concat(important, ";\n align-items: center").concat(important, ";\n gap: 8px").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer .ttp-info-btn {\n position: absolute").concat(important, ";\n right: 12px").concat(important, ";\n margin-left: auto").concat(important, ";\n }\n .text-interface-powered {\n color: rgba(255,255,255,0.46)").concat(important, ";\n font-size: 10px").concat(important, ";\n line-height: 1.2").concat(important, ";\n text-align: center").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-powered a {\n color: ").concat(sendButtonColor).concat(important, ";\n text-decoration: none").concat(important, ";\n }\n .text-interface.active ~ .ttp-footer {\n display: none").concat(important, ";\n }\n \n .input-wrapper {\n position: relative").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .message-input {\n width: 100%").concat(important, ";\n min-height: ").concat(TEXT_INPUT_MIN_HEIGHT_PX, "px").concat(important, ";\n max-height: ").concat(TEXT_INPUT_MAX_HEIGHT_PX, "px").concat(important, ";\n padding: ").concat(inputPadding, ";\n border: 1px solid ").concat(inputBorderColor, ";\n border-radius: ").concat(inputBorderRadius, "px;\n font-size: ").concat(inputFontSize, ";\n font-family: inherit").concat(important, ";\n line-height: 1.4").concat(important, ";\n resize: none").concat(important, ";\n overflow-y: auto").concat(important, ";\n background: ").concat(inputBackgroundColor, ";\n color: ").concat(inputTextColor, ";\n vertical-align: top").concat(important, ";\n margin: 0").concat(important, ";\n display: block").concat(important, ";\n white-space: pre-wrap").concat(important, ";\n word-wrap: break-word").concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n unicode-bidi: plaintext").concat(important, ";\n -webkit-appearance: none").concat(important, ";\n appearance: none").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n \n .message-input:focus {\n outline: none").concat(important, ";\n border-color: ").concat(inputFocusColor, ";\n background: ").concat(inputFocusBg).concat(important, ";\n box-shadow: ").concat(inputFocusBoxShadow, ";\n }\n \n .message-input::placeholder {\n color: ").concat(placeholderColor).concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n \n .send-button {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n background: linear-gradient(135deg, ").concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")").concat(important, ";\n color: ").concat(sendButtonTextColor, ";\n font-size: ").concat(this.config.sendButtonFontSize || ((_this$config$panel15 = this.config.panel) === null || _this$config$panel15 === void 0 ? void 0 : _this$config$panel15.sendButtonFontSize) || '16px', ";\n font-weight: ").concat(this.config.sendButtonFontWeight || ((_this$config$panel16 = this.config.panel) === null || _this$config$panel16 === void 0 ? void 0 : _this$config$panel16.sendButtonFontWeight) || '500', ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n transition: all 0.2s ease").concat(important, ";\n box-shadow: 0 4px 12px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.32)").concat(important, ";\n }\n .send-icon {\n width: 18px").concat(important, ";\n height: 18px").concat(important, ";\n fill: none").concat(important, ";\n stroke: currentColor").concat(important, ";\n stroke-width: 2.1").concat(important, ";\n stroke-linecap: round").concat(important, ";\n stroke-linejoin: round").concat(important, ";\n }\n \n .send-button:hover:not(:disabled) {\n background: ").concat(sendButtonHoverColor, ";\n transform: scale(1.05)").concat(important, ";\n box-shadow: 0 6px 16px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.42)").concat(important, ";\n }\n \n .send-button-hint {\n width: 100%").concat(important, ";\n text-align: center").concat(important, ";\n margin-top: 4px").concat(important, ";\n }\n \n .send-button:disabled {\n opacity: 0.5").concat(important, ";\n cursor: not-allowed").concat(important, ";\n }\n \n .typing-indicator {\n display: inline-flex").concat(important, ";\n gap: 4px").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .typing-dot {\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", ").concat(typingDotAlpha, ")").concat(important, ";\n animation: typingDot 1.4s ease-in-out infinite").concat(important, ";\n }\n \n .typing-dot:nth-child(2) { animation-delay: 0.2s").concat(important, "; }\n .typing-dot:nth-child(3) { animation-delay: 0.4s").concat(important, "; }\n \n @keyframes typingDot {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.7; }\n 30% { transform: translateY(-8px); opacity: 1; }\n }\n \n .error-message {\n padding: 12px").concat(important, ";\n background: ").concat(errorBubbleBg, ";\n border-radius: ").concat(messages.borderRadius, "px;\n color: ").concat(errorBubbleColor).concat(important, ";\n border: ").concat(errorBubbleBorder).concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n \n ").concat(useVoiceTheme ? "\n #textInterface.active .input-container .send-button-hint {\n color: rgba(255,255,255,0.72)".concat(important, ";\n }\n ") : '', "\n \n @media (max-width: 768px) {\n #messagesContainer {\n padding: 12px").concat(important, ";\n gap: 12px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 85%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 12px 62px 12px 14px").concat(important, ";\n padding-right: 62px").concat(important, ";\n }\n \n .text-input-container {\n padding: 10px").concat(important, ";\n gap: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 10px 14px").concat(important, ";\n min-height: 44px").concat(important, ";\n }\n \n #text-chat-send {\n min-width: 56px").concat(important, ";\n min-height: 44px").concat(important, ";\n width: 56px").concat(important, ";\n height: 44px").concat(important, ";\n }\n \n .empty-state-icon {\n font-size: 44px").concat(important, ";\n }\n \n .empty-state-title {\n font-size: 20px").concat(important, ";\n }\n \n .empty-state-text {\n font-size: 14px").concat(important, ";\n }\n }\n \n @media (max-width: 480px) {\n #messagesContainer {\n padding: 10px").concat(important, ";\n gap: 10px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 90%").concat(important, ";\n font-size: ").concat(messages.fontSize).concat(important, ";\n padding: 10px 62px 10px 12px").concat(important, ";\n padding-right: 62px").concat(important, ";\n }\n \n .text-input-container {\n padding: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important;\n padding: 8px 12px").concat(important, ";\n }\n }\n ");
|
|
38048
|
+
return "\n .text-interface-top-bar {\n flex-shrink: 0".concat(important, ";\n padding: 12px 14px").concat(important, ";\n border-bottom: 1px solid ").concat(topBarBorder).concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: flex-start").concat(important, ";\n gap: 10px").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface-agent-heading {\n display: flex").concat(important, ";\n flex-direction: row").concat(important, ";\n align-items: center").concat(important, ";\n gap: 9px").concat(important, ";\n min-width: 0").concat(important, ";\n flex: 1").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .text-interface-agent-avatar {\n width: 36px").concat(important, ";\n height: 36px").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex: 0 0 36px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: ").concat(useVoiceTheme ? avatarAgentBg : "linear-gradient(135deg, ".concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")")).concat(important, ";\n border: none").concat(important, ";\n box-shadow: none").concat(important, ";\n }\n .text-interface-agent-initial { color: #fff").concat(important, "; font-size: 14px").concat(important, "; font-weight: 500").concat(important, "; line-height: 1").concat(important, "; }\n .text-interface-agent-copy {\n display: flex").concat(important, ";\n flex-direction: column").concat(important, ";\n align-items: flex-start").concat(important, ";\n gap: 2px").concat(important, ";\n min-width: 0").concat(important, ";\n }\n .text-interface-agent-name {\n color: #f0eff8").concat(important, ";\n font-size: 14px").concat(important, ";\n font-weight: 500").concat(important, ";\n line-height: 1.15").concat(important, ";\n overflow: hidden").concat(important, ";\n text-overflow: ellipsis").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-agent-status {\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 6px").concat(important, ";\n color: rgba(255,255,255,0.7)").concat(important, ";\n font-size: 10px").concat(important, ";\n }\n .text-interface-agent-status > span {\n width: 7px").concat(important, ";\n height: 7px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: #4ade80").concat(important, ";\n box-shadow: 0 0 10px rgba(74,222,128,0.75)").concat(important, ";\n }\n .text-interface-top-actions { display: flex").concat(important, "; align-items: center").concat(important, "; gap: 4px").concat(important, "; margin-inline-start: auto").concat(important, "; }\n .text-interface-close-btn:hover,\n .text-interface-home-btn:hover,\n .text-interface-footer .ttp-info-btn:hover {\n background: rgba(255,255,255,0.22)").concat(important, ";\n color: #ffffff").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.26), 0 4px 14px rgba(0,0,0,0.22)").concat(important, ";\n }\n .text-interface-close-btn,\n .text-interface-home-btn,\n .text-interface-footer .ttp-info-btn {\n width: 32px").concat(important, ";\n height: 32px").concat(important, ";\n display: grid").concat(important, ";\n place-items: center").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n border: 1px solid rgba(255,255,255,0.14)").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n cursor: pointer").concat(important, ";\n font-family: inherit").concat(important, ";\n transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease").concat(important, ";\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.14)").concat(important, ";\n }\n .text-interface-home-btn svg,\n .text-interface-close-btn svg,\n .text-interface-footer .ttp-info-btn svg { width: 18px").concat(important, "; height: 18px").concat(important, "; fill: none").concat(important, "; stroke: currentColor").concat(important, "; stroke-width: 1.9").concat(important, "; stroke-linecap: round").concat(important, "; stroke-linejoin: round").concat(important, "; }\n .text-interface-home-btn svg { fill: none").concat(important, "; stroke: currentColor").concat(important, "; width: 20px").concat(important, "; height: 20px").concat(important, "; stroke-width: 1.8").concat(important, "; }\n .input-container .text-interface-home-btn {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n color: rgba(224,218,255,0.84)").concat(important, ";\n background: rgba(255,255,255,0.12)").concat(important, ";\n flex-shrink: 0").concat(important, ";\n }\n /* Messages container using new classes */\n #messagesContainer { \n flex: 1").concat(important, "; \n overflow-y: auto").concat(important, "; \n overflow-x: hidden").concat(important, "; \n padding: 20px").concat(important, "; \n background: ").concat(messagesAreaBg).concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n gap: 16px").concat(important, "; \n min-height: 0").concat(important, "; \n }\n .empty-state { \n flex: 1").concat(important, "; \n display: flex").concat(important, "; \n flex-direction: column").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n gap: 12px").concat(important, "; \n color: ").concat(emptyMuted).concat(important, "; \n text-align: center").concat(important, "; \n padding: 20px").concat(important, "; \n }\n .empty-state-icon { font-size: 52px").concat(important, "; opacity: 0.3").concat(important, "; }\n .empty-state-title { font-size: 22px").concat(important, "; font-weight: 700").concat(important, "; color: ").concat(emptyTitle).concat(important, "; }\n .empty-state-text { font-size: 15px").concat(important, "; max-width: 300px").concat(important, "; line-height: 1.45").concat(important, "; }\n .empty-state-icon {\n width: 48px").concat(important, "; height: 48px").concat(important, "; border-radius: 16px").concat(important, ";\n display: grid").concat(important, "; place-items: center").concat(important, "; color: rgba(230,225,255,0.9)").concat(important, ";\n background: rgba(255,255,255,0.1)").concat(important, ";\n border: 1px solid rgba(225,219,255,0.18)").concat(important, ";\n }\n .empty-state-icon svg { width: 24px").concat(important, "; height: 24px").concat(important, "; }\n\n .text-interface { \n display: none").concat(important, "; \n flex: 1").concat(important, "; \n flex-direction: column").concat(important, "; \n min-height: 0").concat(important, "; \n overflow: hidden").concat(important, "; \n direction: ").concat(textDirection).concat(important, ";\n }\n .text-interface.active { display: flex").concat(important, "; }\n \n .message { \n display: flex").concat(important, "; \n flex-direction: column").concat(important, ";\n gap: 4px").concat(important, ";\n padding: 4px 0").concat(important, "; \n width: 100%").concat(important, ";\n max-width: 100%").concat(important, "; \n align-items: stretch").concat(important, ";\n }\n .message-bubble { \n position: relative").concat(important, ";\n padding: 10px ").concat(MESSAGE_META_GUTTER_PX, "px 10px 14px").concat(important, ";\n border-radius: 14px").concat(important, ";\n max-width: min(72%, 440px)").concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n line-height: 1.45").concat(important, ";\n word-wrap: break-word").concat(important, "; \n box-shadow: ").concat(useVoiceTheme ? 'inset 0 1px 0 rgba(255,255,255,0.36), inset 0 -1px 0 rgba(5, 3, 26, 0.18), 0 8px 20px rgba(4, 3, 22, 0.24)' : 'none').concat(important, ";\n }\n .message-bubble[dir=\"rtl\"] { text-align: right").concat(important, "; direction: rtl").concat(important, "; }\n .message-bubble[dir=\"ltr\"] { text-align: left").concat(important, "; direction: ltr").concat(important, "; }\n .message-bubble::before {\n content: ''").concat(important, ";\n position: absolute").concat(important, ";\n top: 1px").concat(important, ";\n right: 1px").concat(important, ";\n left: 1px").concat(important, ";\n height: 48%").concat(important, ";\n border-radius: 11px 11px 8px 8px").concat(important, ";\n background: linear-gradient(180deg, rgba(255,255,255,0.19), rgba(255,255,255,0))").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-bubble { \n background: ").concat(userBubbleBg).concat(important, "; \n color: ").concat(userBubbleTextColor).concat(important, "; \n border-top-right-radius: 4px").concat(important, ";\n }\n .message.agent .message-bubble {\n background: ").concat(agentBubbleBg).concat(important, ";\n color: ").concat(agentBubbleTextColor).concat(important, ";\n border: ").concat(agentBubbleBorder).concat(important, ";\n border-top-left-radius: 4px").concat(important, ";\n }\n\n /* ---------------------------------------------------------------\n Rendered markdown inside the agent bubble.\n Everything is scoped to .message-bubble so host-page styles can't\n reach in and the user bubble (plain text) is untouched.\n Logical properties (padding-inline-start, border-inline-start) keep\n the layout correct in RTL locales such as Hebrew.\n ---------------------------------------------------------------- */\n .message-bubble.md, .message-bubble .md-seg { line-height: 1.55").concat(important, "; }\n .message-bubble .md-seg { display: block").concat(important, "; }\n\n .message-bubble p {\n margin: 0 0 10px").concat(important, ";\n padding: 0").concat(important, ";\n }\n /* Deliberately gated on .md / .md-seg rather than a bare\n \".message-bubble > *\": the VOICE live-transcript row reuses the\n .message-bubble class in this same shadow root, and its children\n (.live-badge, .ttp-cursor) are not ours to restyle. */\n .message-bubble.md > *:last-child,\n .message-bubble .md-seg:last-child > *:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble.md > *:first-child,\n .message-bubble .md-seg:first-child > *:first-child { margin-top: 0").concat(important, "; }\n\n .message-bubble .md-h {\n margin: 16px 0 7px").concat(important, ";\n padding: 0").concat(important, ";\n font-weight: 700").concat(important, ";\n line-height: 1.3").concat(important, ";\n color: inherit").concat(important, ";\n }\n .message-bubble .md-h1 { font-size: 1.18em").concat(important, "; }\n .message-bubble .md-h2 { font-size: 1.09em").concat(important, "; }\n .message-bubble .md-h3 { font-size: 1.02em").concat(important, "; }\n .message-bubble .md-h4,\n .message-bubble .md-h5,\n .message-bubble .md-h6 {\n font-size: 0.95em").concat(important, ";\n letter-spacing: 0.02em").concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n\n /* Logical properties only \u2014 a physical padding-left/border-left after\n these would resolve to the same property and silently win in LTR. */\n .message-bubble ul, .message-bubble ol {\n margin: 8px 0 11px").concat(important, ";\n padding-inline-start: 1.45em").concat(important, ";\n list-style-position: outside").concat(important, ";\n }\n .message-bubble ul { list-style-type: disc").concat(important, "; }\n .message-bubble ol { list-style-type: decimal").concat(important, "; }\n .message-bubble ul ul { list-style-type: circle").concat(important, "; }\n .message-bubble li {\n margin: 0 0 5px").concat(important, ";\n padding: 0").concat(important, ";\n line-height: 1.5").concat(important, ";\n }\n .message-bubble li:last-child { margin-bottom: 0").concat(important, "; }\n .message-bubble li::marker { color: ").concat(mdAccent).concat(important, "; }\n .message-bubble li > ul, .message-bubble li > ol { margin: 5px 0 2px").concat(important, "; }\n .message-bubble li > p { margin: 0 0 5px").concat(important, "; }\n\n .message-bubble strong, .message-bubble b { font-weight: 700").concat(important, "; }\n .message-bubble em, .message-bubble i { font-style: italic").concat(important, "; }\n .message-bubble del { text-decoration: line-through").concat(important, "; opacity: 0.7").concat(important, "; }\n\n .message-bubble a {\n color: ").concat(mdLink).concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n word-break: break-word").concat(important, ";\n }\n .message-bubble a:hover { opacity: 0.82").concat(important, "; }\n\n .message-bubble code {\n font-family: ").concat(mdMono).concat(important, ";\n font-size: 0.88em").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 5px").concat(important, ";\n padding: 1px 5px").concat(important, ";\n white-space: break-spaces").concat(important, ";\n word-break: break-word").concat(important, ";\n direction: ltr").concat(important, ";\n unicode-bidi: embed").concat(important, ";\n }\n .message-bubble pre {\n margin: 10px 0 11px").concat(important, ";\n padding: 10px 12px").concat(important, ";\n background: ").concat(mdSubtleBg).concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 10px").concat(important, ";\n overflow-x: auto").concat(important, ";\n direction: ltr").concat(important, ";\n text-align: left").concat(important, ";\n }\n .message-bubble pre code {\n background: none").concat(important, ";\n border: none").concat(important, ";\n border-radius: 0").concat(important, ";\n padding: 0").concat(important, ";\n font-size: 0.85em").concat(important, ";\n line-height: 1.5").concat(important, ";\n white-space: pre").concat(important, ";\n word-break: normal").concat(important, ";\n }\n\n .message-bubble blockquote {\n margin: 10px 0").concat(important, ";\n padding-block: 2px").concat(important, ";\n padding-inline-start: 12px").concat(important, ";\n padding-inline-end: 0").concat(important, ";\n border-inline-start: 3px solid ").concat(mdAccent).concat(important, ";\n color: ").concat(mdMuted).concat(important, ";\n }\n .message-bubble blockquote > *:last-child { margin-bottom: 0").concat(important, "; }\n\n .message-bubble hr {\n border: none").concat(important, ";\n border-top: 1px solid ").concat(mdRule).concat(important, ";\n height: 0").concat(important, ";\n margin: 13px 0").concat(important, ";\n }\n\n .message-bubble .md-table-wrap {\n margin: 10px 0 11px").concat(important, ";\n overflow-x: auto").concat(important, ";\n border: 1px solid ").concat(mdBorder).concat(important, ";\n border-radius: 9px").concat(important, ";\n }\n .message-bubble table {\n border-collapse: collapse").concat(important, ";\n width: 100%").concat(important, ";\n font-size: 0.93em").concat(important, ";\n }\n .message-bubble th, .message-bubble td {\n padding: 7px 11px").concat(important, ";\n text-align: start").concat(important, ";\n border-bottom: 1px solid ").concat(mdBorder).concat(important, ";\n vertical-align: top").concat(important, ";\n }\n .message-bubble thead th {\n background: ").concat(mdSubtleBg).concat(important, ";\n font-weight: 700").concat(important, ";\n }\n .message-bubble tbody tr:nth-child(even) { background: ").concat(mdSubtlerBg).concat(important, "; }\n .message-bubble tbody tr:last-child td { border-bottom: none").concat(important, "; }\n\n .message-bubble .md-img {\n display: block").concat(important, ";\n max-width: 100%").concat(important, ";\n height: auto").concat(important, ";\n border-radius: 8px").concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n\n .message.user { \n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.agent {\n align-self: stretch").concat(important, ";\n align-items: stretch").concat(important, ";\n }\n .message.user .message-bubble {\n margin-left: auto").concat(important, ";\n margin-right: 0").concat(important, ";\n }\n .message.agent .message-bubble {\n margin-left: 0").concat(important, ";\n margin-right: auto").concat(important, ";\n }\n .message-meta {\n position: absolute").concat(important, ";\n right: ").concat(MESSAGE_META_INSET_PX, "px").concat(important, ";\n bottom: 9px").concat(important, ";\n z-index: 2").concat(important, ";\n display: inline-flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 5px").concat(important, ";\n margin: 0").concat(important, ";\n color: rgba(255,255,255,0.55)").concat(important, ";\n font-size: 10px").concat(important, ";\n line-height: 1").concat(important, ";\n direction: ltr").concat(important, ";\n white-space: nowrap").concat(important, ";\n pointer-events: none").concat(important, ";\n }\n .message.user .message-meta {\n color: rgba(255,255,255,0.74)").concat(important, ";\n }\n .message-content { position: relative").concat(important, "; z-index: 1").concat(important, "; display: inline").concat(important, "; overflow-wrap: anywhere").concat(important, "; word-break: break-word").concat(important, "; direction: inherit").concat(important, "; }\n .message-meta-spacer { display: inline-block").concat(important, "; width: 0").concat(important, "; height: 1px").concat(important, "; }\n .message-delivery-checks { color: rgba(255,255,255,0.92)").concat(important, "; font-weight: 700").concat(important, "; letter-spacing: -2px").concat(important, "; }\n .message-expand-button {\n position: relative").concat(important, ";\n z-index: 3").concat(important, ";\n margin: 0 4px").concat(important, ";\n padding: 0").concat(important, ";\n border: 0").concat(important, ";\n background: transparent").concat(important, ";\n color: #c4b5fd").concat(important, ";\n font: inherit").concat(important, ";\n font-size: 0.78em").concat(important, ";\n font-weight: 600").concat(important, ";\n line-height: inherit").concat(important, ";\n text-decoration: underline").concat(important, ";\n text-underline-offset: 2px").concat(important, ";\n cursor: pointer").concat(important, ";\n }\n .message-expand-button:hover { color: #ede9fe").concat(important, "; }\n .message-avatar { \n width: ").concat(avatarSize).concat(important, "; \n height: ").concat(avatarSize).concat(important, "; \n min-width: ").concat(avatarSize).concat(important, "; \n border-radius: 50%").concat(important, "; \n display: flex").concat(important, "; \n align-items: center").concat(important, "; \n justify-content: center").concat(important, "; \n flex-shrink: 0").concat(important, "; \n color: inherit").concat(important, "; \n font-size: ").concat(useVoiceTheme ? '14' : '20', "px").concat(important, "; \n line-height: 1").concat(important, "; \n background: transparent").concat(important, "; \n border: none").concat(important, "; \n box-sizing: border-box").concat(important, "; \n }\n .message-avatar.user { background: ").concat(avatarUserBg).concat(important, "; color: ").concat(avatarUserColor).concat(important, "; }\n .message-avatar.agent { background: ").concat(avatarAgentBg).concat(important, "; }\n \n .message.system {\n background: ").concat(messages.systemBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n .message.error {\n background: ").concat(messages.errorBackgroundColor, ";\n align-self: flex-start").concat(important, ";\n }\n \n .input-container {\n display: flex").concat(important, ";\n gap: 8px").concat(important, ";\n padding: 12px 16px").concat(important, ";\n background: ").concat(inputContainerBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n align-items: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n flex-direction: row").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer {\n position: relative").concat(important, ";\n flex-shrink: 0").concat(important, ";\n min-height: 28px").concat(important, ";\n padding: 4px 12px").concat(important, ";\n background: ").concat(topBarBg).concat(important, ";\n border-top: 1px solid ").concat(inputContainerBorderTop).concat(important, ";\n display: flex").concat(important, ";\n justify-content: center").concat(important, ";\n align-items: center").concat(important, ";\n gap: 8px").concat(important, ";\n direction: ltr").concat(important, ";\n }\n .text-interface-footer .ttp-info-btn {\n position: absolute").concat(important, ";\n right: 12px").concat(important, ";\n margin-left: auto").concat(important, ";\n }\n .text-interface-powered {\n color: rgba(255,255,255,0.46)").concat(important, ";\n font-size: 10px").concat(important, ";\n line-height: 1.2").concat(important, ";\n text-align: center").concat(important, ";\n white-space: nowrap").concat(important, ";\n }\n .text-interface-powered a {\n color: ").concat(sendButtonColor).concat(important, ";\n text-decoration: none").concat(important, ";\n }\n .text-interface.active ~ .ttp-footer {\n display: none").concat(important, ";\n }\n \n .input-wrapper {\n position: relative").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .message-input {\n width: 100%").concat(important, ";\n min-height: ").concat(TEXT_INPUT_MIN_HEIGHT_PX, "px").concat(important, ";\n max-height: ").concat(TEXT_INPUT_MAX_HEIGHT_PX, "px").concat(important, ";\n padding: ").concat(inputPadding, ";\n border: 1px solid ").concat(inputBorderColor, ";\n border-radius: ").concat(inputBorderRadius, "px;\n font-size: ").concat(inputFontSize, ";\n font-family: inherit").concat(important, ";\n line-height: 1.4").concat(important, ";\n resize: none").concat(important, ";\n overflow-y: auto").concat(important, ";\n background: ").concat(inputBackgroundColor, ";\n color: ").concat(inputTextColor, ";\n vertical-align: top").concat(important, ";\n margin: 0").concat(important, ";\n display: block").concat(important, ";\n white-space: pre-wrap").concat(important, ";\n word-wrap: break-word").concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n unicode-bidi: plaintext").concat(important, ";\n -webkit-appearance: none").concat(important, ";\n appearance: none").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n \n .message-input:focus {\n outline: none").concat(important, ";\n border-color: ").concat(inputFocusColor, ";\n background: ").concat(inputFocusBg).concat(important, ";\n box-shadow: ").concat(inputFocusBoxShadow, ";\n }\n \n .message-input::placeholder {\n color: ").concat(placeholderColor).concat(important, ";\n text-align: start").concat(important, ";\n direction: ").concat(textDirection).concat(important, ";\n }\n \n .send-button {\n width: 38px").concat(important, ";\n height: 38px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n background: linear-gradient(135deg, ").concat(sendButtonColor, ", ").concat(sendButtonHoverColor, ")").concat(important, ";\n color: ").concat(sendButtonTextColor, ";\n font-size: ").concat(this.config.sendButtonFontSize || ((_this$config$panel15 = this.config.panel) === null || _this$config$panel15 === void 0 ? void 0 : _this$config$panel15.sendButtonFontSize) || '16px', ";\n font-weight: ").concat(this.config.sendButtonFontWeight || ((_this$config$panel16 = this.config.panel) === null || _this$config$panel16 === void 0 ? void 0 : _this$config$panel16.sendButtonFontWeight) || '500', ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n flex-shrink: 0").concat(important, ";\n transition: all 0.2s ease").concat(important, ";\n box-shadow: 0 4px 12px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.32)").concat(important, ";\n }\n .send-icon {\n width: 18px").concat(important, ";\n height: 18px").concat(important, ";\n fill: none").concat(important, ";\n stroke: currentColor").concat(important, ";\n stroke-width: 2.1").concat(important, ";\n stroke-linecap: round").concat(important, ";\n stroke-linejoin: round").concat(important, ";\n }\n \n .send-button:hover:not(:disabled) {\n background: ").concat(sendButtonHoverColor, ";\n transform: scale(1.05)").concat(important, ";\n box-shadow: 0 6px 16px rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", 0.42)").concat(important, ";\n }\n \n .send-button-hint {\n width: 100%").concat(important, ";\n text-align: center").concat(important, ";\n margin-top: 4px").concat(important, ";\n }\n \n .send-button:disabled {\n opacity: 0.5").concat(important, ";\n cursor: not-allowed").concat(important, ";\n }\n \n .typing-indicator {\n display: inline-flex").concat(important, ";\n gap: 4px").concat(important, ";\n align-items: center").concat(important, ";\n }\n \n .typing-dot {\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n border-radius: 50%").concat(important, ";\n background: rgba(").concat(accentRgb[0], ", ").concat(accentRgb[1], ", ").concat(accentRgb[2], ", ").concat(typingDotAlpha, ")").concat(important, ";\n animation: typingDot 1.4s ease-in-out infinite").concat(important, ";\n }\n \n .typing-dot:nth-child(2) { animation-delay: 0.2s").concat(important, "; }\n .typing-dot:nth-child(3) { animation-delay: 0.4s").concat(important, "; }\n \n @keyframes typingDot {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.7; }\n 30% { transform: translateY(-8px); opacity: 1; }\n }\n \n .error-message {\n padding: 12px").concat(important, ";\n background: ").concat(errorBubbleBg, ";\n border-radius: ").concat(messages.borderRadius, "px;\n color: ").concat(errorBubbleColor).concat(important, ";\n border: ").concat(errorBubbleBorder).concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n margin: 8px 0").concat(important, ";\n }\n \n ").concat(useVoiceTheme ? "\n #textInterface.active .input-container .send-button-hint {\n color: rgba(255,255,255,0.72)".concat(important, ";\n }\n ") : '', "\n \n @media (max-width: 768px) {\n #messagesContainer {\n padding: 12px").concat(important, ";\n gap: 12px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 85%").concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n padding: 11px ").concat(MESSAGE_META_GUTTER_PX, "px 11px 14px").concat(important, ";\n }\n \n .text-input-container {\n padding: 10px").concat(important, ";\n gap: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important; /* Prevents iOS zoom on focus */\n padding: 10px 14px").concat(important, ";\n min-height: 44px").concat(important, ";\n }\n \n #text-chat-send {\n min-width: 56px").concat(important, ";\n min-height: 44px").concat(important, ";\n width: 56px").concat(important, ";\n height: 44px").concat(important, ";\n }\n \n .empty-state-icon {\n font-size: 44px").concat(important, ";\n }\n \n .empty-state-title {\n font-size: 20px").concat(important, ";\n }\n \n .empty-state-text {\n font-size: 14px").concat(important, ";\n }\n }\n \n @media (max-width: 480px) {\n #messagesContainer {\n padding: 10px").concat(important, ";\n gap: 10px").concat(important, ";\n }\n \n .message-bubble {\n max-width: 90%").concat(important, ";\n font-size: ").concat(messageFontSize).concat(important, ";\n padding: 10px ").concat(MESSAGE_META_GUTTER_PX, "px 10px 13px").concat(important, ";\n }\n \n .text-input-container {\n padding: 8px").concat(important, ";\n }\n \n #text-chat-input {\n font-size: 16px !important;\n padding: 8px 12px").concat(important, ";\n }\n }\n ");
|
|
37773
38049
|
}
|
|
37774
38050
|
|
|
37775
38051
|
/**
|
|
@@ -38418,10 +38694,11 @@ var TextInterface = /*#__PURE__*/function () {
|
|
|
38418
38694
|
errorContainer.appendChild(message);
|
|
38419
38695
|
messages.appendChild(errorContainer);
|
|
38420
38696
|
} else {
|
|
38421
|
-
|
|
38697
|
+
var text = typeof error === 'string' ? error : error && error.message;
|
|
38698
|
+
if (!text) return;
|
|
38422
38699
|
var errorEl = document.createElement('div');
|
|
38423
38700
|
errorEl.className = 'error-message';
|
|
38424
|
-
errorEl.textContent =
|
|
38701
|
+
errorEl.textContent = text;
|
|
38425
38702
|
messages.appendChild(errorEl);
|
|
38426
38703
|
}
|
|
38427
38704
|
messages.scrollTop = messages.scrollHeight;
|