@xapp/chat-widget 1.97.0 → 1.98.0

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/index.es.js CHANGED
@@ -320,13 +320,14 @@ const color_1 = color;
320
320
  /** Fallback when a crawl found no branding. Deliberately neutral. */
321
321
  const DEFAULT_PRIMARY = "#1AA7DC";
322
322
  function buildChatWidgetChannel(props) {
323
+ var _a;
323
324
  const { appId, apiUrl, mcpUrl, formWidgetKey, phoneNumber } = props;
325
+ const businessName = (_a = props.businessName) === null || _a === void 0 ? void 0 : _a.trim();
324
326
  // Only a colour whose contrast can actually be computed, so the background
325
327
  // and the text on it are always a matched pair rather than one scraped
326
328
  // value and one guess.
327
329
  const primaryColor = (0, color_1.usableColorOr)(props.primaryColor, DEFAULT_PRIMARY);
328
- return {
329
- type: "chat-widget",
330
+ return Object.assign({ type: "chat-widget",
330
331
  // MCP by default. The widget runs on a public page, so homeowner mode
331
332
  // — which is unauthenticated and carries the appId in the url — is the
332
333
  // only one that can work there; business_owner needs a token, and a
@@ -337,10 +338,7 @@ function buildChatWidgetChannel(props) {
337
338
  mcp: {
338
339
  mode: "homeowner"
339
340
  }
340
- },
341
- theme: buildChatTheme(primaryColor, props.secondaryColor),
342
- actionBar: buildActionBar({ apiUrl, formWidgetKey, phoneNumber })
343
- };
341
+ }, theme: buildChatTheme(primaryColor, props.secondaryColor), actionBar: buildActionBar({ apiUrl, formWidgetKey, phoneNumber }) }, (businessName ? { botName: businessName } : {}));
344
342
  }
345
343
  /**
346
344
  * The dock of buttons that replaces the plain chat bubble.
@@ -1134,15 +1132,15 @@ PERFORMANCE OF THIS SOFTWARE.
1134
1132
  /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1135
1133
 
1136
1134
 
1137
- var __assign = function() {
1138
- __assign = Object.assign || function __assign(t) {
1135
+ var __assign$1 = function() {
1136
+ __assign$1 = Object.assign || function __assign(t) {
1139
1137
  for (var s, i = 1, n = arguments.length; i < n; i++) {
1140
1138
  s = arguments[i];
1141
1139
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1142
1140
  }
1143
1141
  return t;
1144
1142
  };
1145
- return __assign.apply(this, arguments);
1143
+ return __assign$1.apply(this, arguments);
1146
1144
  };
1147
1145
 
1148
1146
  function __rest(s, e) {
@@ -1719,7 +1717,7 @@ function useServerConfig(env, nonce) {
1719
1717
  */
1720
1718
  function foldChannelId(mcp, channelId) {
1721
1719
  var _a;
1722
- return mcp ? __assign(__assign({}, mcp), { channelId: (_a = mcp.channelId) !== null && _a !== void 0 ? _a : channelId }) : mcp;
1720
+ return mcp ? __assign$1(__assign$1({}, mcp), { channelId: (_a = mcp.channelId) !== null && _a !== void 0 ? _a : channelId }) : mcp;
1723
1721
  }
1724
1722
  function useConnectionInfo(env) {
1725
1723
  var nonce = useSelector(function (state) { return state.connection.nonce; });
@@ -2429,9 +2427,9 @@ function executeAction(text, meta) {
2429
2427
  return function (chatServer) { return function (dispatch, getState) {
2430
2428
  // add in attributes from meta
2431
2429
  var attributes = getState().attributes;
2432
- attributes = __assign(__assign({}, attributes), { currentUrl: window.location.href });
2430
+ attributes = __assign$1(__assign$1({}, attributes), { currentUrl: window.location.href });
2433
2431
  var _a = meta || {}, token = _a.token, rest = __rest(_a, ["token"]);
2434
- attributes = __assign(__assign({}, attributes), rest);
2432
+ attributes = __assign$1(__assign$1({}, attributes), rest);
2435
2433
  // Add user message to Redux BEFORE sending to server
2436
2434
  // to ensure it appears above the bot's streaming response
2437
2435
  var visitor = getState().visitor;
@@ -3088,6 +3086,17 @@ PERFORMANCE OF THIS SOFTWARE.
3088
3086
  /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
3089
3087
 
3090
3088
 
3089
+ var __assign = function() {
3090
+ __assign = Object.assign || function __assign(t) {
3091
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
3092
+ s = arguments[i];
3093
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
3094
+ }
3095
+ return t;
3096
+ };
3097
+ return __assign.apply(this, arguments);
3098
+ };
3099
+
3091
3100
  function __awaiter(thisArg, _arguments, P, generator) {
3092
3101
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3093
3102
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -3321,6 +3330,162 @@ function useSuggestionsFetch$1(options) {
3321
3330
  return response;
3322
3331
  }
3323
3332
 
3333
+ /**
3334
+ * Marketing attribution capture, shared by every widget surface.
3335
+ *
3336
+ * The chat widget historically sent only `currentUrl`, which meant attribution
3337
+ * survived only when the visitor opened the chat on the very page the ad landed
3338
+ * them on. Anyone who browsed first arrived unattributed. These helpers capture
3339
+ * the parameters on first sight and persist them, so a conversation started three
3340
+ * pages later still carries the click that paid for it.
3341
+ *
3342
+ * Only the parameters below are ever read or stored. The query string as a whole
3343
+ * is not, because it routinely carries session tokens and PII.
3344
+ */
3345
+ /** Standard UTM parameters. */
3346
+ var UTM_PARAMETERS = [
3347
+ "utm_source",
3348
+ "utm_medium",
3349
+ "utm_campaign",
3350
+ "utm_term",
3351
+ "utm_content"
3352
+ ];
3353
+ /**
3354
+ * Platform click ids.
3355
+ *
3356
+ * `gbraid` and `wbraid` are what Google substitutes for `gclid` when the click
3357
+ * cannot be tied to a cookie — iOS and consent-mode traffic. For home services,
3358
+ * where most paid traffic is mobile, omitting them loses attribution on the
3359
+ * majority of the spend.
3360
+ */
3361
+ var CLICK_ID_PARAMETERS = [
3362
+ "gclid",
3363
+ "gbraid",
3364
+ "wbraid",
3365
+ "msclkid",
3366
+ "fbclid"
3367
+ ];
3368
+ var ATTRIBUTION_PARAMETERS = __spreadArray(__spreadArray([], UTM_PARAMETERS, true), CLICK_ID_PARAMETERS);
3369
+ var STORAGE_KEY_PREFIX = "xa_tracking_";
3370
+ /** Matches the 30 day window the form widget already uses. */
3371
+ var DEFAULT_PERSISTENCE_DAYS = 30;
3372
+ var MAX_VALUE_LENGTH = 255;
3373
+ /**
3374
+ * Values land in a request body and, downstream, in a CRM. Cap the length and
3375
+ * reject anything carrying markup or control characters.
3376
+ */
3377
+ function isValidValue(value) {
3378
+ // eslint-disable-next-line no-control-regex
3379
+ return value.length <= MAX_VALUE_LENGTH && !/[<>"'\x00-\x1f]/.test(value);
3380
+ }
3381
+ /**
3382
+ * Reads the attribution parameters present on a URL. Never throws — a URL we
3383
+ * cannot parse simply contributes nothing.
3384
+ */
3385
+ function extractAttributionFromUrl(url) {
3386
+ var parsed;
3387
+ try {
3388
+ parsed = new URL(url);
3389
+ }
3390
+ catch (_a) {
3391
+ return {};
3392
+ }
3393
+ var attribution = {};
3394
+ ATTRIBUTION_PARAMETERS.forEach(function (parameter) {
3395
+ var value = parsed.searchParams.get(parameter);
3396
+ if (value && isValidValue(value)) {
3397
+ attribution[parameter] = value;
3398
+ }
3399
+ });
3400
+ return attribution;
3401
+ }
3402
+ /**
3403
+ * Persists attribution for later conversations. Existing values are overwritten,
3404
+ * so the most recent click wins, matching how the ad platforms attribute.
3405
+ */
3406
+ function storeAttribution(attribution, persistenceDays) {
3407
+ if (persistenceDays === void 0) { persistenceDays = DEFAULT_PERSISTENCE_DAYS; }
3408
+ var expires = Date.now() + persistenceDays * 24 * 60 * 60 * 1000;
3409
+ Object.entries(attribution).forEach(function (_a) {
3410
+ var key = _a[0], value = _a[1];
3411
+ if (!value) {
3412
+ return;
3413
+ }
3414
+ try {
3415
+ localStorage.setItem("".concat(STORAGE_KEY_PREFIX).concat(key), JSON.stringify({ value: value, expires: expires }));
3416
+ }
3417
+ catch (_b) {
3418
+ // Storage can be full or blocked by the browser. Attribution is best
3419
+ // effort — never let it break the conversation.
3420
+ }
3421
+ });
3422
+ }
3423
+ /** Reads back unexpired stored attribution, cleaning up anything unreadable. */
3424
+ function getStoredAttribution() {
3425
+ var attribution = {};
3426
+ ATTRIBUTION_PARAMETERS.forEach(function (parameter) {
3427
+ var key = "".concat(STORAGE_KEY_PREFIX).concat(parameter);
3428
+ var stored;
3429
+ try {
3430
+ stored = localStorage.getItem(key);
3431
+ }
3432
+ catch (_a) {
3433
+ return;
3434
+ }
3435
+ if (!stored) {
3436
+ return;
3437
+ }
3438
+ try {
3439
+ var parsed = JSON.parse(stored);
3440
+ if (parsed && parsed.expires > Date.now() && typeof parsed.value === "string") {
3441
+ attribution[parameter] = parsed.value;
3442
+ }
3443
+ else {
3444
+ localStorage.removeItem(key);
3445
+ }
3446
+ }
3447
+ catch (_b) {
3448
+ localStorage.removeItem(key);
3449
+ }
3450
+ });
3451
+ return attribution;
3452
+ }
3453
+ /**
3454
+ * The attribution to send with a request: whatever is stored, with anything on
3455
+ * the current URL layered on top, and the current URL's values persisted for
3456
+ * subsequent pages.
3457
+ */
3458
+ function getAttribution(url) {
3459
+ if (url === void 0) { url = window.location.href; }
3460
+ var fromUrl = extractAttributionFromUrl(url);
3461
+ if (Object.keys(fromUrl).length > 0) {
3462
+ storeAttribution(fromUrl);
3463
+ }
3464
+ return __assign(__assign({}, getStoredAttribution()), fromUrl);
3465
+ }
3466
+ /**
3467
+ * Strips the query string from a URL, leaving origin + pathname.
3468
+ *
3469
+ * Referrers and page URLs routinely carry session tokens, email addresses and other
3470
+ * PII in their query strings, and a referrer captured at session start is sent with
3471
+ * every subsequent message — so the raw value must never be stored. Attribution is
3472
+ * read separately, by allowlist, before this is applied.
3473
+ *
3474
+ * Returns undefined for an empty or unparseable URL rather than passing it through.
3475
+ */
3476
+ function stripQueryString(url) {
3477
+ if (!url) {
3478
+ return undefined;
3479
+ }
3480
+ try {
3481
+ var parsed = new URL(url);
3482
+ return parsed.origin + parsed.pathname;
3483
+ }
3484
+ catch (_a) {
3485
+ return undefined;
3486
+ }
3487
+ }
3488
+
3324
3489
  /**
3325
3490
  * Stop the host page scrolling behind an open overlay.
3326
3491
  *
@@ -3602,13 +3767,14 @@ function uuid() {
3602
3767
  });
3603
3768
  return newUuid;
3604
3769
  }
3605
-
3606
3770
  var IconButton_1 = IconButton;
3607
3771
  var RichInput_1 = RichInput;
3608
3772
  var SuggestionsList_1 = SuggestionsList;
3609
3773
  var findItemByIndex_1 = findItemByIndex;
3774
+ var getAttribution_1 = getAttribution;
3610
3775
  var getItemsLength_1 = getItemsLength;
3611
3776
  var parseSuggestionsResponse_1 = parseSuggestionsResponse;
3777
+ var stripQueryString_1 = stripQueryString;
3612
3778
  var useBodyScrollLock_1 = useBodyScrollLock;
3613
3779
  var useSuggestionsFetch_1 = useSuggestionsFetch$1;
3614
3780
  var useVisualViewportProperties_1 = useVisualViewportProperties;
@@ -4066,7 +4232,19 @@ function getLocalISOString(date) {
4066
4232
  * PRIVACY NOTE: Query strings are stripped from URLs by default as they
4067
4233
  * may contain sensitive data (tokens, PII). Only origin + pathname are sent.
4068
4234
  */
4235
+ /**
4236
+ * Reads attribution for the current page, or undefined when there is none or there is
4237
+ * no browser to read it from.
4238
+ */
4239
+ function collectAttribution() {
4240
+ if (typeof window === "undefined") {
4241
+ return undefined;
4242
+ }
4243
+ var attribution = getAttribution_1(window.location.href);
4244
+ return Object.keys(attribution).length > 0 ? attribution : undefined;
4245
+ }
4069
4246
  function getPageContext(override) {
4247
+ var _a;
4070
4248
  var localTime = getLocalISOString();
4071
4249
  // If override provided, merge with defaults (override wins)
4072
4250
  // Overrides are typically for testing and may include full URLs
@@ -4077,6 +4255,14 @@ function getPageContext(override) {
4077
4255
  path: override.path,
4078
4256
  title: override.title,
4079
4257
  referrer: override.referrer,
4258
+ // Never skip attribution just because the page context was overridden.
4259
+ // The public knob is WidgetEnv.mcp.pageContextOverride, typed
4260
+ // PageContextOverride -- url/path/title/referrer, with no attribution
4261
+ // field -- and an SPA integrator sets it on every virtual route change.
4262
+ // Taking override.attribution alone would therefore be undefined for every
4263
+ // real caller, silently disabling attribution on the MCP path for exactly
4264
+ // the browse-then-chat case this exists to capture.
4265
+ attribution: (_a = override.attribution) !== null && _a !== void 0 ? _a : collectAttribution(),
4080
4266
  localTime: localTime,
4081
4267
  };
4082
4268
  }
@@ -4085,23 +4271,18 @@ function getPageContext(override) {
4085
4271
  }
4086
4272
  // Strip query strings from URL for privacy (may contain tokens/PII)
4087
4273
  var urlWithoutQuery = window.location.origin + window.location.pathname;
4088
- // Strip query strings from referrer as well
4089
- var referrerWithoutQuery;
4090
- if (document.referrer) {
4091
- try {
4092
- var refUrl = new URL(document.referrer);
4093
- referrerWithoutQuery = refUrl.origin + refUrl.pathname;
4094
- }
4095
- catch (_a) {
4096
- // Invalid referrer URL, skip it
4097
- referrerWithoutQuery = undefined;
4098
- }
4099
- }
4274
+ // Strip query strings from referrer as well -- shared with StentorDirectChat so the
4275
+ // two chat paths cannot disagree about what is safe to send.
4276
+ var referrerWithoutQuery = stripQueryString_1(document.referrer);
4277
+ // Pull the attribution parameters out BEFORE the query string is discarded.
4278
+ // Only the known utm_* and click id keys are read; everything else in the
4279
+ // query string stays stripped, so the privacy posture above is unchanged.
4100
4280
  return {
4101
4281
  url: urlWithoutQuery,
4102
4282
  path: window.location.pathname,
4103
4283
  title: document.title || undefined,
4104
4284
  referrer: referrerWithoutQuery,
4285
+ attribution: collectAttribution(),
4105
4286
  localTime: localTime,
4106
4287
  };
4107
4288
  }
@@ -4233,7 +4414,7 @@ var MCPChat = /** @class */ (function () {
4233
4414
  */
4234
4415
  MCPChat.prototype.buildRequestPayload = function (additionalData) {
4235
4416
  if (additionalData === void 0) { additionalData = {}; }
4236
- return __assign(__assign({
4417
+ return __assign$1(__assign$1({
4237
4418
  // Identity - server generates these, we just send back what we have
4238
4419
  userId: this._userId || undefined, sessionId: this._sessionId || undefined,
4239
4420
  // Fingerprint for user identification (can be disabled for privacy)
@@ -4696,12 +4877,12 @@ var MCPChat = /** @class */ (function () {
4696
4877
  if (!user) {
4697
4878
  // Ensure bot nick has agent: prefix and mark as AI
4698
4879
  var defaultBot = bot || { nick: "agent:robot", displayName: "Assistant" };
4699
- return __assign(__assign({}, defaultBot), { nick: this.ensureAgentNick(defaultBot.nick), isAI: true });
4880
+ return __assign$1(__assign$1({}, defaultBot), { nick: this.ensureAgentNick(defaultBot.nick), isAI: true });
4700
4881
  }
4701
4882
  if (user.displayName && user.nick && user.avatarPath) {
4702
- return __assign(__assign({}, user), { nick: this.ensureAgentNick(user.nick), isAI: true });
4883
+ return __assign$1(__assign$1({}, user), { nick: this.ensureAgentNick(user.nick), isAI: true });
4703
4884
  }
4704
- return __assign(__assign({}, user), { nick: this.ensureAgentNick(user.nick || (bot === null || bot === void 0 ? void 0 : bot.nick)), displayName: user.displayName || (bot === null || bot === void 0 ? void 0 : bot.displayName) || "Assistant", avatarPath: user.avatarPath || (bot === null || bot === void 0 ? void 0 : bot.avatarPath), isAI: true });
4885
+ return __assign$1(__assign$1({}, user), { nick: this.ensureAgentNick(user.nick || (bot === null || bot === void 0 ? void 0 : bot.nick)), displayName: user.displayName || (bot === null || bot === void 0 ? void 0 : bot.displayName) || "Assistant", avatarPath: user.avatarPath || (bot === null || bot === void 0 ? void 0 : bot.avatarPath), isAI: true });
4705
4886
  };
4706
4887
  MCPChat.prototype.sendChatMsgRequest = function (serviceRequest, cb) {
4707
4888
  return __awaiter$1(this, void 0, void 0, function () {
@@ -4883,7 +5064,7 @@ var MCPChat = /** @class */ (function () {
4883
5064
  // WARNING: Do not log headers object - it contains sensitive auth tokens
4884
5065
  cjs.fetchEventSource(endpoint, {
4885
5066
  method: "POST",
4886
- headers: __assign({ "Content-Type": "application/json" }, ((_this.config.mode || "homeowner") === "business_owner" && _this.config.authToken
5067
+ headers: __assign$1({ "Content-Type": "application/json" }, ((_this.config.mode || "homeowner") === "business_owner" && _this.config.authToken
4887
5068
  ? { Authorization: "Bearer ".concat(_this.config.authToken) }
4888
5069
  : {})),
4889
5070
  body: JSON.stringify(body),
@@ -5184,7 +5365,7 @@ var MCPChat = /** @class */ (function () {
5184
5365
  MCPChat.prototype.sendTyping = function () { };
5185
5366
  MCPChat.prototype.setVisitorInfo = function (visitorInfo, sessionId, cb) {
5186
5367
  this.visitorInfo = visitorInfo;
5187
- this._attributes = __assign({}, this.visitorInfo.attributes);
5368
+ this._attributes = __assign$1({}, this.visitorInfo.attributes);
5188
5369
  // do not set currentUrl if localhost
5189
5370
  var href = new URL(window.location.href);
5190
5371
  if (href === null || href === void 0 ? void 0 : href.host.toLowerCase().startsWith("localhost")) {
@@ -5424,6 +5605,35 @@ var MCPChat = /** @class */ (function () {
5424
5605
  return MCPChat;
5425
5606
  }());
5426
5607
 
5608
+ /**
5609
+ * Builds the attribute set for one outgoing message.
5610
+ *
5611
+ * Returns a **fresh object every call**. That is the point of this function, not an
5612
+ * incidental detail: the chat server's `_attributes` is a single object that lives for
5613
+ * the whole conversation, so writing attribution into it directly means the first value
5614
+ * seen is the value sent forever. A visitor who navigates within an SPA to a page with a
5615
+ * different `gclid` would keep sending the original one, which contradicts the
5616
+ * most-recent-click-wins behaviour `attribution.ts` documents and the ad platforms
5617
+ * assume.
5618
+ *
5619
+ * Precedence: whatever the host page set explicitly wins, because that was deliberate.
5620
+ * Everything else comes from the current attribution read.
5621
+ *
5622
+ * @param hostAttributes attributes the host page set at session start
5623
+ * @param attribution the attribution resolved for this message
5624
+ */
5625
+ function mergeAttribution(hostAttributes, attribution) {
5626
+ var host = hostAttributes || {};
5627
+ var merged = __assign$1({}, attribution);
5628
+ for (var _i = 0, _a = Object.entries(host); _i < _a.length; _i++) {
5629
+ var _b = _a[_i], key = _b[0], value = _b[1];
5630
+ if (value !== undefined) {
5631
+ merged[key] = value;
5632
+ }
5633
+ }
5634
+ return merged;
5635
+ }
5636
+
5427
5637
  /**
5428
5638
  * Sends a POST to your STENTOR based server.
5429
5639
  *
@@ -5600,10 +5810,10 @@ function responseToMessage(botResponse, now) {
5600
5810
  user: undefined
5601
5811
  };
5602
5812
  if (text && !html) {
5603
- responseMessage.msg = __assign(__assign({}, responseMessage.msg), { text: text });
5813
+ responseMessage.msg = __assign$1(__assign$1({}, responseMessage.msg), { text: text });
5604
5814
  }
5605
5815
  if (html) {
5606
- responseMessage.msg = __assign(__assign({}, responseMessage.msg), { html: html });
5816
+ responseMessage.msg = __assign$1(__assign$1({}, responseMessage.msg), { html: html });
5607
5817
  }
5608
5818
  if ((_e = outputSpeech === null || outputSpeech === void 0 ? void 0 : outputSpeech.suggestions) === null || _e === void 0 ? void 0 : _e.length) {
5609
5819
  responseMessage.msg.options = outputSpeech.suggestions.map(function (suggestion) {
@@ -5699,7 +5909,7 @@ var StentorDirectChat = /** @class */ (function () {
5699
5909
  type: "chat",
5700
5910
  detail: {
5701
5911
  type: "chat.msg",
5702
- user: __assign(__assign({}, data.user), { nick: "agent:robot" }),
5912
+ user: __assign$1(__assign$1({}, data.user), { nick: "agent:robot" }),
5703
5913
  msg: data.msg,
5704
5914
  timestamp: +new Date(),
5705
5915
  },
@@ -5711,7 +5921,7 @@ var StentorDirectChat = /** @class */ (function () {
5711
5921
  type: "chat",
5712
5922
  detail: {
5713
5923
  type: "chat.memberjoin",
5714
- user: __assign(__assign({}, data.user), { nick: "agent:robot" }),
5924
+ user: __assign$1(__assign$1({}, data.user), { nick: "agent:robot" }),
5715
5925
  timestamp: +new Date(),
5716
5926
  },
5717
5927
  });
@@ -5826,7 +6036,7 @@ var StentorDirectChat = /** @class */ (function () {
5826
6036
  if (user.displayName && user.nick && user.avatarPath) {
5827
6037
  return user;
5828
6038
  }
5829
- return __assign(__assign({}, user), { nick: user.nick || bot.nick || "Bot", displayName: user.displayName || bot.displayName || "Bot", avatarPath: user.avatarPath || bot.avatarPath });
6039
+ return __assign$1(__assign$1({}, user), { nick: user.nick || bot.nick || "Bot", displayName: user.displayName || bot.displayName || "Bot", avatarPath: user.avatarPath || bot.avatarPath });
5830
6040
  };
5831
6041
  StentorDirectChat.prototype.sendChatMsgRequest = function (serviceRequest, cb) {
5832
6042
  return __awaiter$1(this, void 0, void 0, function () {
@@ -5838,7 +6048,7 @@ var StentorDirectChat = /** @class */ (function () {
5838
6048
  case 1:
5839
6049
  agentResponse = _b.sent();
5840
6050
  if (!((_a = agentResponse.user) === null || _a === void 0 ? void 0 : _a.displayName)) {
5841
- agentResponse = __assign(__assign({}, agentResponse), { user: this.getBot(agentResponse.user) });
6051
+ agentResponse = __assign$1(__assign$1({}, agentResponse), { user: this.getBot(agentResponse.user) });
5842
6052
  }
5843
6053
  this.sendNewMessage(agentResponse);
5844
6054
  cb();
@@ -5850,7 +6060,7 @@ var StentorDirectChat = /** @class */ (function () {
5850
6060
  StentorDirectChat.prototype.sendTyping = function () { };
5851
6061
  StentorDirectChat.prototype.setVisitorInfo = function (visitorInfo, sessionId, cb) {
5852
6062
  this.visitorInfo = visitorInfo;
5853
- this._attributes = __assign({}, this.visitorInfo.attributes);
6063
+ this._attributes = __assign$1({}, this.visitorInfo.attributes);
5854
6064
  // do not set currentUrl if localhost, localhost is not liked by some firewalls, like AWS WAF
5855
6065
  var href = new URL(window.location.href);
5856
6066
  if (href === null || href === void 0 ? void 0 : href.host.toLowerCase().startsWith("localhost")) {
@@ -5861,6 +6071,18 @@ var StentorDirectChat = /** @class */ (function () {
5861
6071
  // not localhost, set it
5862
6072
  this._attributes.currentUrl = window.location.href;
5863
6073
  }
6074
+ // The page the visitor arrived FROM, which is a separate attribution signal
6075
+ // from currentUrl — the page they arrived ON.
6076
+ //
6077
+ // Stored WITHOUT its query string. A referrer captured here lives in
6078
+ // _attributes for the whole conversation and is sent with every message, and
6079
+ // referrer query strings routinely carry session tokens and email addresses.
6080
+ // The attribution parameters are read separately, by allowlist, so nothing of
6081
+ // value is lost by dropping the rest.
6082
+ var referrer = stripQueryString_1(document.referrer);
6083
+ if (referrer) {
6084
+ this._attributes.referrer = referrer;
6085
+ }
5864
6086
  this._accessToken = this.visitorInfo.accessToken;
5865
6087
  // This is for the bot
5866
6088
  this.userJoined({
@@ -5892,7 +6114,7 @@ var StentorDirectChat = /** @class */ (function () {
5892
6114
  userId = this._userId;
5893
6115
  sessionId = this._sessionId;
5894
6116
  accessToken = this._accessToken;
5895
- attributes = this._attributes || {};
6117
+ attributes = mergeAttribution(this._attributes, getAttribution_1());
5896
6118
  rwgToken = localStorage.getItem("xa_rwg_token");
5897
6119
  if (rwgToken) {
5898
6120
  attributes["rwg_token"] = rwgToken;
@@ -5937,7 +6159,7 @@ var StentorDirectChat = /** @class */ (function () {
5937
6159
  else {
5938
6160
  permissionRequest = (_c = message.msg) === null || _c === void 0 ? void 0 : _c.permissionRequest;
5939
6161
  if (permissionRequest) {
5940
- message = __assign(__assign({}, message), { msg: __assign(__assign({}, message.msg), { permissionRequest: undefined }) });
6162
+ message = __assign$1(__assign$1({}, message), { msg: __assign$1(__assign$1({}, message.msg), { permissionRequest: undefined }) });
5941
6163
  expired = now - permissionRequest.time > PERMISSION_QUESTION_EXPIRATION_MS$1;
5942
6164
  text = (_d = message.msg.text) === null || _d === void 0 ? void 0 : _d.toLowerCase();
5943
6165
  granted = !expired;
@@ -5978,7 +6200,7 @@ var StentorDirectChat = /** @class */ (function () {
5978
6200
  };
5979
6201
  }
5980
6202
  else if (message.type === "custom") {
5981
- request = __assign(__assign({}, JSON.parse(message.payload)), {
6203
+ request = __assign$1(__assign$1({}, JSON.parse(message.payload)), {
5982
6204
  // token: message.msg.token,
5983
6205
  sessionId: this._sessionId, userId: this._userId, isNewSession: false,
5984
6206
  // intentId: "OptionSelect",
@@ -6209,7 +6431,7 @@ function requestFromMessage(message, userId, isNewSession, sessionId, accessToke
6209
6431
  // Pending permission request?
6210
6432
  var permissionRequest = (_c = message.msg) === null || _c === void 0 ? void 0 : _c.permissionRequest;
6211
6433
  if (permissionRequest) {
6212
- message = __assign(__assign({}, message), { msg: __assign(__assign({}, message.msg), { permissionRequest: undefined }) });
6434
+ message = __assign$1(__assign$1({}, message), { msg: __assign$1(__assign$1({}, message.msg), { permissionRequest: undefined }) });
6213
6435
  var expired = now - permissionRequest.time > PERMISSION_QUESTION_EXPIRATION_MS;
6214
6436
  var text = (_d = message.msg.text) === null || _d === void 0 ? void 0 : _d.toLowerCase();
6215
6437
  var granted = !expired;
@@ -6248,7 +6470,7 @@ function requestFromMessage(message, userId, isNewSession, sessionId, accessToke
6248
6470
  };
6249
6471
  }
6250
6472
  else if (message.type === "custom") {
6251
- request = __assign(__assign({}, JSON.parse(message.payload)), {
6473
+ request = __assign$1(__assign$1({}, JSON.parse(message.payload)), {
6252
6474
  // token: message.msg.token,
6253
6475
  sessionId: sessionId, userId: userId, isNewSession: false,
6254
6476
  // intentId: "OptionSelect",
@@ -6284,7 +6506,7 @@ function requestFromMessage(message, userId, isNewSession, sessionId, accessToke
6284
6506
  }
6285
6507
  }
6286
6508
  if ((_e = message.msg) === null || _e === void 0 ? void 0 : _e.attributes) {
6287
- request.attributes = __assign(__assign({}, request.attributes), message.msg.attributes);
6509
+ request.attributes = __assign$1(__assign$1({}, request.attributes), message.msg.attributes);
6288
6510
  }
6289
6511
  return request;
6290
6512
  }
@@ -6446,7 +6668,7 @@ var StentorRouterChat = /** @class */ (function () {
6446
6668
  var response = data;
6447
6669
  // Extract router-managed attributes from message root (adjacent to event, data, sender, etc.)
6448
6670
  if (attributes && typeof attributes === "object" && Object.keys(attributes).length > 0) {
6449
- _this.routerAttributes = __assign({}, attributes);
6671
+ _this.routerAttributes = __assign$1({}, attributes);
6450
6672
  log("Extracted router attributes: ".concat(JSON.stringify(_this.routerAttributes)));
6451
6673
  }
6452
6674
  if (typeof ((_a = _this.options.hooks) === null || _a === void 0 ? void 0 : _a.onResponse) === "function") {
@@ -6953,7 +7175,7 @@ var StentorRouterChat = /** @class */ (function () {
6953
7175
  isAdmin: this.isAdmin,
6954
7176
  urlAttributes: this.urlAttributes,
6955
7177
  };
6956
- this.attributes = __assign(__assign(__assign({}, visitorInfoMessage.attributes), this.attributes), { currentUrl: window.location.href });
7178
+ this.attributes = __assign$1(__assign$1(__assign$1({}, visitorInfoMessage.attributes), this.attributes), { currentUrl: window.location.href });
6957
7179
  this.accessToken = visitorInfoMessage.accessToken;
6958
7180
  this.startSession(sessionId);
6959
7181
  this.postVisitorInfo(); // we, the widget, joined the server
@@ -12209,7 +12431,7 @@ var MultiSelect = function (props) {
12209
12431
  var handleToggle = useCallback(function (ev) {
12210
12432
  var _a;
12211
12433
  var id = ev.target.value;
12212
- onChange(__assign(__assign({}, checked), (_a = {}, _a[id] = !checked[id], _a)));
12434
+ onChange(__assign$1(__assign$1({}, checked), (_a = {}, _a[id] = !checked[id], _a)));
12213
12435
  }, [checked, onChange]);
12214
12436
  return (jsx("ul", { className: "xappw-multiselect", children: items === null || items === void 0 ? void 0 : items.map(function (item) { return (jsx("li", { children: jsxs("label", { children: [jsx("input", { type: "checkbox", checked: checked[item.id] || false, onChange: handleToggle, value: item.id }), jsx("span", { children: item.title })] }) }, item.id)); }) }));
12215
12437
  };
@@ -12925,7 +13147,7 @@ function useGreeting(active) {
12925
13147
  visitorId: curr.visitorId,
12926
13148
  userId: curr.userId,
12927
13149
  accessToken: curr.accessToken,
12928
- attributes: __assign(__assign({}, curr.attributes), { currentUrl: window.location.href })
13150
+ attributes: __assign$1(__assign$1({}, curr.attributes), { currentUrl: window.location.href })
12929
13151
  }, sessionId));
12930
13152
  if (!isAdmin) {
12931
13153
  var timeoutId_1 = setTimeout(function () {
@@ -34757,7 +34979,7 @@ function dateTimeToSpeech(value, type) {
34757
34979
  // If it is a time only, we need to just add the
34758
34980
  // current date for parsing. It won't be spoken
34759
34981
  // back to the user, just for parsing.
34760
- var toParse = __assign({}, value);
34982
+ var toParse = __assign$1({}, value);
34761
34983
  if (!toParse.date) {
34762
34984
  toParse.date = ("yyyy-MM-dd");
34763
34985
  }
@@ -35294,7 +35516,7 @@ var MessageList = function (_a) {
35294
35516
  case "chat.msg":
35295
35517
  return (jsx(ChatMessage, { message: msg, sibling: sibling, agent: user, messageMiddleware: messageMiddleware, middlewareContext: ctxCache.resolve(user), minimizeOnClick: minimizeOnClick }, "cm-".concat(msg.type, "-").concat(msg.timestamp)));
35296
35518
  case "chat.failureMsg":
35297
- return (jsx(FailureMessage, __assign({ agents: agents, time: time }, msg.failureMsg), "fm-".concat(msg.type, "-").concat(msg.timestamp)));
35519
+ return (jsx(FailureMessage, __assign$1({ agents: agents, time: time }, msg.failureMsg), "fm-".concat(msg.type, "-").concat(msg.timestamp)));
35298
35520
  case "chat.memberjoin":
35299
35521
  case "chat.memberleave":
35300
35522
  case "chat.systemmessage":
@@ -35834,11 +36056,11 @@ var ErrorOverlay = function (_a) {
35834
36056
  if (lastError && lastError.message === error.message) {
35835
36057
  // Update count of last error
35836
36058
  return __spreadArray$1(__spreadArray$1([], prev.slice(0, -1), true), [
35837
- __assign(__assign({}, lastError), { count: lastError.count + 1, timestamp: timestamp }),
36059
+ __assign$1(__assign$1({}, lastError), { count: lastError.count + 1, timestamp: timestamp }),
35838
36060
  ], false);
35839
36061
  }
35840
36062
  // Add new error
35841
- var newError = __assign({ id: "".concat(timestamp, "-").concat(Math.random()), timestamp: timestamp, count: 1 }, error);
36063
+ var newError = __assign$1({ id: "".concat(timestamp, "-").concat(Math.random()), timestamp: timestamp, count: 1 }, error);
35842
36064
  // Keep only last 50 errors
35843
36065
  var updated = __spreadArray$1(__spreadArray$1([], prev, true), [newError], false);
35844
36066
  return updated.slice(-50);
@@ -36065,7 +36287,7 @@ function createDefaultState(state, options) {
36065
36287
  debugMode = true;
36066
36288
  }
36067
36289
  }
36068
- return __assign({ connection: {
36290
+ return __assign$1({ connection: {
36069
36291
  connectionStatus: "offline",
36070
36292
  token: null,
36071
36293
  greetingRequested: false
@@ -36080,7 +36302,7 @@ function createStateFromMessages(messages) {
36080
36302
  var lastMessage = messages.length > 0 ? messages[messages.length - 1] : undefined;
36081
36303
  var lastMsg = (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.type) === "chat.msg" ? lastMessage.msg : null;
36082
36304
  var chips = ((_a = lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.options) === null || _a === void 0 ? void 0 : _a.length) ? lastMsg.options : [];
36083
- return __assign(__assign({}, def), { connection: __assign(__assign({}, def.connection), { connectionStatus: "online" }), accountStatus: "online", chats: __spreadArray$1([], messages, true), chips: chips, isChatting: true, visuals: {
36305
+ return __assign$1(__assign$1({}, def), { connection: __assign$1(__assign$1({}, def.connection), { connectionStatus: "online" }), accountStatus: "online", chats: __spreadArray$1([], messages, true), chips: chips, isChatting: true, visuals: {
36084
36306
  visible: true,
36085
36307
  opened: true,
36086
36308
  } });
@@ -36561,12 +36783,12 @@ var StaticChatWidgetContainer = function (props) {
36561
36783
  return createStaticStore(state);
36562
36784
  }, [state]);
36563
36785
  var config = useMemo(function () {
36564
- return __assign(__assign({}, props.config), { connection: {
36786
+ return __assign$1(__assign$1({}, props.config), { connection: {
36565
36787
  serverUrl: "",
36566
36788
  type: "local",
36567
36789
  } });
36568
36790
  }, [props.config]);
36569
- return (jsx(Provider, { store: store, children: jsx(ChatWidgetUI, __assign({}, props, { config: config, disableAutoScroll: props.disableAutoScroll, preview: props.preview })) }));
36791
+ return (jsx(Provider, { store: store, children: jsx(ChatWidgetUI, __assign$1({}, props, { config: config, disableAutoScroll: props.disableAutoScroll, preview: props.preview })) }));
36570
36792
  };
36571
36793
 
36572
36794
  var StaticMessagesChatWidgetContainer = function (props) {
@@ -36706,7 +36928,7 @@ var ChatWidgetConnected = function (props) {
36706
36928
  var connection = useConnectionInfo(rawConfig);
36707
36929
  var config = useMemo(function () {
36708
36930
  var _a;
36709
- return (__assign(__assign({}, rawConfig), { connection: connection, assetUrl: (_a = connection === null || connection === void 0 ? void 0 : connection.serverUrl) !== null && _a !== void 0 ? _a : defaultServerUrl, env: rawConfig }));
36931
+ return (__assign$1(__assign$1({}, rawConfig), { connection: connection, assetUrl: (_a = connection === null || connection === void 0 ? void 0 : connection.serverUrl) !== null && _a !== void 0 ? _a : defaultServerUrl, env: rawConfig }));
36710
36932
  }, [connection, rawConfig]);
36711
36933
  var token = useSelector(function (state) { return state.connection.token; });
36712
36934
  var options = useMemo(function () {
@@ -36746,7 +36968,7 @@ var ChatWidgetConnected = function (props) {
36746
36968
  if (configError) {
36747
36969
  return (jsx("div", { className: "widget-container widget-container--error ".concat(modeClass), children: jsxs("div", { className: "widget-error-message", children: ["Failed to load chat configuration: ", configError.message] }) }));
36748
36970
  }
36749
- return (jsx(ChatConfigContext.Provider, { value: config, children: jsx(ChatServerContext.Provider, { value: chatServer, children: jsx(ChatWidgetUI, __assign({}, props, { config: rawConfig })) }) }));
36971
+ return (jsx(ChatConfigContext.Provider, { value: config, children: jsx(ChatServerContext.Provider, { value: chatServer, children: jsx(ChatWidgetUI, __assign$1({}, props, { config: rawConfig })) }) }));
36750
36972
  };
36751
36973
  /**
36752
36974
  * Inner ChatWidget component that renders the actual UI.
@@ -37095,7 +37317,7 @@ var ChatWidgetUI = function (props) {
37095
37317
  // Update the button state to show it's pressed
37096
37318
  innerDispatch({
37097
37319
  type: "ws_button_display",
37098
- detail: __assign(__assign({}, chatState.wsButton), { isPressed: true, timestamp: +new Date() })
37320
+ detail: __assign$1(__assign$1({}, chatState.wsButton), { isPressed: true, timestamp: +new Date() })
37099
37321
  });
37100
37322
  }
37101
37323
  // Send the button pressed event to the server
@@ -37106,7 +37328,7 @@ var ChatWidgetUI = function (props) {
37106
37328
  if (chatState.wsButton) {
37107
37329
  innerDispatch({
37108
37330
  type: "ws_button_display",
37109
- detail: __assign(__assign({}, chatState.wsButton), { isPressed: false, timestamp: +new Date() })
37331
+ detail: __assign$1(__assign$1({}, chatState.wsButton), { isPressed: false, timestamp: +new Date() })
37110
37332
  });
37111
37333
  }
37112
37334
  });
@@ -37116,7 +37338,7 @@ var ChatWidgetUI = function (props) {
37116
37338
  // First set dismissing state to trigger animation
37117
37339
  innerDispatch({
37118
37340
  type: "ws_button_display",
37119
- detail: __assign(__assign({}, chatState.wsButton), { isDismissing: true, timestamp: +new Date() })
37341
+ detail: __assign$1(__assign$1({}, chatState.wsButton), { isDismissing: true, timestamp: +new Date() })
37120
37342
  });
37121
37343
  // Then actually dismiss after animation completes
37122
37344
  setTimeout(function () {
@@ -37204,7 +37426,7 @@ var ChatWidgetUI = function (props) {
37204
37426
  avatarPath: config.avatarUrl,
37205
37427
  display_name: "Agent",
37206
37428
  };
37207
- return (jsxs(Fragment, { children: [jsxs("div", { className: "widget-container ".concat(modeClass, " ").concat(getVisibilityClass()).concat(actionBarVisible ? " widget-container--with-action-bar" : ""), children: [jsx(WidgetStylesheet, { theme: config === null || config === void 0 ? void 0 : config.theme }), jsx(ChatHeader, { accountStatus: chatState.accountStatus, refreshOnClick: handleRestartClick, minimizeOnClick: handleMinimizeClick, cancelOnClick: handleCancelClick, agent: widgetAgent, canRefresh: canRefresh, canMinimize: canMinimize, canCancel: canCancel, config: config === null || config === void 0 ? void 0 : config.header, menuConfig: config.menu, debugMode: (_x = (_w = (_v = props.config) === null || _v === void 0 ? void 0 : _v.connection) === null || _w === void 0 ? void 0 : _w.mcp) === null || _x === void 0 ? void 0 : _x.debugMode, onSubmit: handleOnSubmit }), jsx(MessageList, { visible: visible, queuePosition: chatState.queuePosition, isChatting: chatState.isChatting, isOffline: isOffline, messages: messages, agents: chatState.agents, agent: config === null || config === void 0 ? void 0 : config.agent, lastRatingRequestTimestamp: chatState.lastRatingRequestTimestamp, hasRating: chatState.hasRating, visitorId: chatState.visitorId, hasWsButton: !!chatState.wsButton, messageMiddleware: props.messageMiddleware, textTypingStatusEnabled: (_z = (_y = props.config) === null || _y === void 0 ? void 0 : _y.typingStatus) === null || _z === void 0 ? void 0 : _z.textTypingStatusEnabled, disableAutoScroll: props.disableAutoScroll, onSend: handleSendMessage, onWrite: handleWriteMessage, onOpenUrl: handleOpenUrl, minimizeOnClick: handleMinimizeClick }), jsx("div", { className: "xa-spinner-container ".concat(visible && connectionStatus === "pending" ? "visible" : ""), children: jsx("div", { className: "xa-spinner" }) }), connectionStatus === "offline" && jsx(ServerOffline, {}), chatState.wsButton && visible && (jsx(WsButton, { button: chatState.wsButton, onPress: handleWsButtonPress })), jsx(ChatFooter, { isAdmin: config === null || config === void 0 ? void 0 : config.isAdmin, isChatting: chatState.isChatting, placeholder: (_0 = config === null || config === void 0 ? void 0 : config.input) === null || _0 === void 0 ? void 0 : _0.placeholder, sendButtonIcon: (_2 = (_1 = config === null || config === void 0 ? void 0 : config.footer) === null || _1 === void 0 ? void 0 : _1.sendButton) === null || _2 === void 0 ? void 0 : _2.icon, sendButtonIconHover: (_4 = (_3 = config === null || config === void 0 ? void 0 : config.footer) === null || _3 === void 0 ? void 0 : _3.sendButton) === null || _4 === void 0 ? void 0 : _4.iconHover, sendButtonIconDisabled: (_6 = (_5 = config === null || config === void 0 ? void 0 : config.footer) === null || _5 === void 0 ? void 0 : _5.sendButton) === null || _6 === void 0 ? void 0 : _6.iconDisabled, visible: visible, hasWsButton: !!chatState.wsButton, menuConfig: (_7 = props.config) === null || _7 === void 0 ? void 0 : _7.menu, footerConfig: (_8 = props.config) === null || _8 === void 0 ? void 0 : _8.footer, inputConfig: (_9 = props.config) === null || _9 === void 0 ? void 0 : _9.input, disabled: previewMode, onChange: handleOnChange, onSubmit: handleOnSubmit, onFileUpload: handleFileUpload }), jsx("div", { className: "restartModal", ref: modalRef, onClick: handleRestartModalCloseClick, children: jsx(ModalContent, { onClose: handleRestartModalCloseClick, onReset: handleReset }) })] }), actionBarVisible && config.actionBar ? (jsxs(Fragment, { children: [jsx(ActionBar, { config: __assign(__assign({}, config.actionBar), {
37429
+ return (jsxs(Fragment, { children: [jsxs("div", { className: "widget-container ".concat(modeClass, " ").concat(getVisibilityClass()).concat(actionBarVisible ? " widget-container--with-action-bar" : ""), children: [jsx(WidgetStylesheet, { theme: config === null || config === void 0 ? void 0 : config.theme }), jsx(ChatHeader, { accountStatus: chatState.accountStatus, refreshOnClick: handleRestartClick, minimizeOnClick: handleMinimizeClick, cancelOnClick: handleCancelClick, agent: widgetAgent, canRefresh: canRefresh, canMinimize: canMinimize, canCancel: canCancel, config: config === null || config === void 0 ? void 0 : config.header, menuConfig: config.menu, debugMode: (_x = (_w = (_v = props.config) === null || _v === void 0 ? void 0 : _v.connection) === null || _w === void 0 ? void 0 : _w.mcp) === null || _x === void 0 ? void 0 : _x.debugMode, onSubmit: handleOnSubmit }), jsx(MessageList, { visible: visible, queuePosition: chatState.queuePosition, isChatting: chatState.isChatting, isOffline: isOffline, messages: messages, agents: chatState.agents, agent: config === null || config === void 0 ? void 0 : config.agent, lastRatingRequestTimestamp: chatState.lastRatingRequestTimestamp, hasRating: chatState.hasRating, visitorId: chatState.visitorId, hasWsButton: !!chatState.wsButton, messageMiddleware: props.messageMiddleware, textTypingStatusEnabled: (_z = (_y = props.config) === null || _y === void 0 ? void 0 : _y.typingStatus) === null || _z === void 0 ? void 0 : _z.textTypingStatusEnabled, disableAutoScroll: props.disableAutoScroll, onSend: handleSendMessage, onWrite: handleWriteMessage, onOpenUrl: handleOpenUrl, minimizeOnClick: handleMinimizeClick }), jsx("div", { className: "xa-spinner-container ".concat(visible && connectionStatus === "pending" ? "visible" : ""), children: jsx("div", { className: "xa-spinner" }) }), connectionStatus === "offline" && jsx(ServerOffline, {}), chatState.wsButton && visible && (jsx(WsButton, { button: chatState.wsButton, onPress: handleWsButtonPress })), jsx(ChatFooter, { isAdmin: config === null || config === void 0 ? void 0 : config.isAdmin, isChatting: chatState.isChatting, placeholder: (_0 = config === null || config === void 0 ? void 0 : config.input) === null || _0 === void 0 ? void 0 : _0.placeholder, sendButtonIcon: (_2 = (_1 = config === null || config === void 0 ? void 0 : config.footer) === null || _1 === void 0 ? void 0 : _1.sendButton) === null || _2 === void 0 ? void 0 : _2.icon, sendButtonIconHover: (_4 = (_3 = config === null || config === void 0 ? void 0 : config.footer) === null || _3 === void 0 ? void 0 : _3.sendButton) === null || _4 === void 0 ? void 0 : _4.iconHover, sendButtonIconDisabled: (_6 = (_5 = config === null || config === void 0 ? void 0 : config.footer) === null || _5 === void 0 ? void 0 : _5.sendButton) === null || _6 === void 0 ? void 0 : _6.iconDisabled, visible: visible, hasWsButton: !!chatState.wsButton, menuConfig: (_7 = props.config) === null || _7 === void 0 ? void 0 : _7.menu, footerConfig: (_8 = props.config) === null || _8 === void 0 ? void 0 : _8.footer, inputConfig: (_9 = props.config) === null || _9 === void 0 ? void 0 : _9.input, disabled: previewMode, onChange: handleOnChange, onSubmit: handleOnSubmit, onFileUpload: handleFileUpload }), jsx("div", { className: "restartModal", ref: modalRef, onClick: handleRestartModalCloseClick, children: jsx(ModalContent, { onClose: handleRestartModalCloseClick, onReset: handleReset }) })] }), actionBarVisible && config.actionBar ? (jsxs(Fragment, { children: [jsx(ActionBar, { config: __assign$1(__assign$1({}, config.actionBar), {
37208
37430
  // Use actionBar.cta if set, otherwise fall back to widget-level cta
37209
37431
  cta: (_10 = config.actionBar.cta) !== null && _10 !== void 0 ? _10 : config.cta }), visible: visible, chatDisabled: config.disabled, formDisabled: isFormPage, hasUserInteracted: (_11 = chatState.visuals) === null || _11 === void 0 ? void 0 : _11.hasInteracted, onChatClick: chatButtonOnClick, onChatMinimize: handleMinimizeClick, onFormClick: handleFormButtonClick, onCtaDismiss: handleCtaDismiss }), formModalOpen && activeFormConfig && (jsx(FormModal, { config: activeFormConfig, widgetEnv: config, onClose: handleFormModalClose }))] })) : (jsx(ChatButton, { addClass: visible ? "visible" : "", onClick: chatButtonOnClick, config: config === null || config === void 0 ? void 0 : config.cta, imageUrl: (_12 = config === null || config === void 0 ? void 0 : config.chatButton) === null || _12 === void 0 ? void 0 : _12.imageUrl, visible: visible, hasInteracted: (_13 = chatState.visuals) === null || _13 === void 0 ? void 0 : _13.hasInteracted, onCtaDismiss: handleCtaDismiss })), jsx(ErrorOverlay, { enableErrorOverlay: config === null || config === void 0 ? void 0 : config.enableErrorOverlay })] }));
37210
37432
  };
@@ -37220,9 +37442,9 @@ var ChatWidgetWrapper = function (props) {
37220
37442
  // For visual layout, use "static" when mode is "preview" (legacy), otherwise use the actual mode
37221
37443
  var visualMode = rawMode === "preview" ? "static" : rawMode;
37222
37444
  if (isPreviewMode) {
37223
- return jsx(ChatWidgetPreview, __assign({}, props, { mode: visualMode }));
37445
+ return jsx(ChatWidgetPreview, __assign$1({}, props, { mode: visualMode }));
37224
37446
  }
37225
- return jsx(ChatWidgetConnected, __assign({}, props));
37447
+ return jsx(ChatWidgetConnected, __assign$1({}, props));
37226
37448
  };
37227
37449
 
37228
37450
  function tryParseJson(str) {
@@ -37302,7 +37524,7 @@ function persistStateReducer(storage, initialState, innerReducer) {
37302
37524
  // Clean up transient visual state on page load - don't persist across browser refreshes
37303
37525
  // visible is derived from config (autoOpenOnWidth, autoOpenOnPattern) and visuals.opened
37304
37526
  if (obj && obj.visuals) {
37305
- obj = __assign(__assign({}, obj), { visuals: __assign(__assign({}, obj.visuals), { hasInteracted: undefined, visible: undefined }) });
37527
+ obj = __assign$1(__assign$1({}, obj), { visuals: __assign$1(__assign$1({}, obj.visuals), { hasInteracted: undefined, visible: undefined }) });
37306
37528
  }
37307
37529
  return function (state, action) {
37308
37530
  if (state === void 0) { state = obj; }
@@ -37315,11 +37537,11 @@ function persistStateReducer(storage, initialState, innerReducer) {
37315
37537
  function connectionReducer(state, action) {
37316
37538
  switch (action.type) {
37317
37539
  case "connection_update":
37318
- return __assign(__assign({}, state), { connectionStatus: action.detail.status });
37540
+ return __assign$1(__assign$1({}, state), { connectionStatus: action.detail.status });
37319
37541
  case "receiveToken":
37320
- return __assign(__assign({}, state), { token: action.detail.token });
37542
+ return __assign$1(__assign$1({}, state), { token: action.detail.token });
37321
37543
  case "sendGreeting":
37322
- return __assign(__assign({}, state), { greetingRequested: true });
37544
+ return __assign$1(__assign$1({}, state), { greetingRequested: true });
37323
37545
  }
37324
37546
  return state;
37325
37547
  }
@@ -37334,9 +37556,9 @@ function memberJoin(state, detail) {
37334
37556
  // console.log(`######### No chats in member join action`);
37335
37557
  // set("sessionId", "");
37336
37558
  // }
37337
- var agents = __assign({}, state.agents);
37559
+ var agents = __assign$1({}, state.agents);
37338
37560
  var prevAgentInfo = state.agents[detail.user.nick];
37339
- agents[detail.user.nick] = __assign(__assign({}, prevAgentInfo), { user: __assign(__assign({}, detail.user), { displayName: detail.user.displayName || "Agent" }), joined: true, typing: false, hideUserInfo: detail.hideUserInfo });
37561
+ agents[detail.user.nick] = __assign$1(__assign$1({}, prevAgentInfo), { user: __assign$1(__assign$1({}, detail.user), { displayName: detail.user.displayName || "Agent" }), joined: true, typing: false, hideUserInfo: detail.hideUserInfo });
37340
37562
  if (isAgent(detail.user.nick)) {
37341
37563
  // Always show join messages with special visual features (divider or custom message)
37342
37564
  // These are important conversation markers, not routine join notifications
@@ -37352,18 +37574,18 @@ function memberJoin(state, detail) {
37352
37574
  log("Agent \"".concat(detail.user.displayName || "Unknown", "\" (nick: ").concat(detail.user.nick, ") is joining. Adding join message to chat."));
37353
37575
  }
37354
37576
  }
37355
- return __assign(__assign({}, state), { isChatting: true, chats: ((prevAgentInfo === null || prevAgentInfo === void 0 ? void 0 : prevAgentInfo.joined) && !hasSpecialVisuals) ? state.chats : joinMessages(state.chats, detail), agents: agents });
37577
+ return __assign$1(__assign$1({}, state), { isChatting: true, chats: ((prevAgentInfo === null || prevAgentInfo === void 0 ? void 0 : prevAgentInfo.joined) && !hasSpecialVisuals) ? state.chats : joinMessages(state.chats, detail), agents: agents });
37356
37578
  }
37357
37579
  else {
37358
37580
  log("Non-agent member \"".concat(detail.user.displayName || "Unknown", "\" (nick: ").concat(detail.user.nick, ") is joining. Adding join message to chat."));
37359
- return __assign(__assign({}, state), { isChatting: true, chats: joinMessages(state.chats, detail), agents: agents });
37581
+ return __assign$1(__assign$1({}, state), { isChatting: true, chats: joinMessages(state.chats, detail), agents: agents });
37360
37582
  }
37361
37583
  }
37362
37584
 
37363
37585
  function memberLeave(state, detail) {
37364
- var agents = __assign({}, state.agents);
37586
+ var agents = __assign$1({}, state.agents);
37365
37587
  var prevAgentInfo = state.agents[detail.user.nick];
37366
- agents[detail.user.nick] = __assign(__assign({}, prevAgentInfo), { joined: false, typing: false });
37588
+ agents[detail.user.nick] = __assign$1(__assign$1({}, prevAgentInfo), { joined: false, typing: false });
37367
37589
  // count number of agents that are still joined
37368
37590
  var agentsJoined = Object.values(agents).filter(function (agent) { return agent.joined; });
37369
37591
  var isChatting = agentsJoined.length > 0;
@@ -37380,11 +37602,11 @@ function memberLeave(state, detail) {
37380
37602
  else {
37381
37603
  log("DEDUPLICATION: Agent \"".concat(detail.user.displayName || "Unknown", "\" (nick: ").concat(detail.user.nick, ") already left. NOT adding duplicate leave message to chat."));
37382
37604
  }
37383
- return __assign(__assign({}, state), { isChatting: isChatting, chats: (prevAgentInfo === null || prevAgentInfo === void 0 ? void 0 : prevAgentInfo.joined) ? joinMessages(state.chats, detail) : state.chats, agents: agents });
37605
+ return __assign$1(__assign$1({}, state), { isChatting: isChatting, chats: (prevAgentInfo === null || prevAgentInfo === void 0 ? void 0 : prevAgentInfo.joined) ? joinMessages(state.chats, detail) : state.chats, agents: agents });
37384
37606
  }
37385
37607
  else {
37386
37608
  log("Non-agent member \"".concat(detail.user.displayName || "Unknown", "\" (nick: ").concat(detail.user.nick, ") is leaving. Adding leave message to chat."));
37387
- return __assign(__assign({}, state), { isChatting: isChatting, chats: joinMessages(state.chats, detail), agents: agents });
37609
+ return __assign$1(__assign$1({}, state), { isChatting: isChatting, chats: joinMessages(state.chats, detail), agents: agents });
37388
37610
  }
37389
37611
  }
37390
37612
 
@@ -37401,7 +37623,7 @@ function resetReducer(state) {
37401
37623
  var wasOnline = state.connection.connectionStatus === 'online';
37402
37624
  // Preserve opened state so widget doesn't close on refresh
37403
37625
  var wasOpened = (_a = state.visuals) === null || _a === void 0 ? void 0 : _a.opened;
37404
- return __assign(__assign({}, defaultState), { connection: __assign(__assign({}, defaultState.connection), { greetingRequested: false,
37626
+ return __assign$1(__assign$1({}, defaultState), { connection: __assign$1(__assign$1({}, defaultState.connection), { greetingRequested: false,
37405
37627
  // Generate new nonce to trigger server recreation and start fresh session
37406
37628
  nonce: uuid_1(),
37407
37629
  // Preserve connection status during transition if we were online
@@ -37455,24 +37677,24 @@ function update(state, action) {
37455
37677
  // workaround until state is split. Use combineReducers afterwards
37456
37678
  var newConnectionState = connectionReducer(state.connection, action);
37457
37679
  if (state.connection !== newConnectionState) {
37458
- state = __assign(__assign({}, state), { lastTimestamp: (_e = action.detail) === null || _e === void 0 ? void 0 : _e.timestamp, connection: newConnectionState });
37680
+ state = __assign$1(__assign$1({}, state), { lastTimestamp: (_e = action.detail) === null || _e === void 0 ? void 0 : _e.timestamp, connection: newConnectionState });
37459
37681
  }
37460
37682
  return state;
37461
37683
  case "account_status":
37462
- return __assign(__assign({}, state), { lastTimestamp: (_f = action.detail) === null || _f === void 0 ? void 0 : _f.timestamp, accountStatus: action.detail.status });
37684
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_f = action.detail) === null || _f === void 0 ? void 0 : _f.timestamp, accountStatus: action.detail.status });
37463
37685
  case "session_id":
37464
- return __assign(__assign({}, state), { lastTimestamp: (_g = action.detail) === null || _g === void 0 ? void 0 : _g.timestamp, sessionId: action.detail.sessionId });
37686
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_g = action.detail) === null || _g === void 0 ? void 0 : _g.timestamp, sessionId: action.detail.sessionId });
37465
37687
  case "visual_status":
37466
- return __assign(__assign({}, state), { lastTimestamp: (_h = action.detail) === null || _h === void 0 ? void 0 : _h.timestamp, visuals: __assign(__assign(__assign(__assign(__assign({}, (state.visuals || {})), (action.detail.status.drawer !== undefined && { drawer: action.detail.status.drawer })), (action.detail.status.opened !== undefined && { opened: action.detail.status.opened })), (action.detail.status.visible !== undefined && { visible: action.detail.status.visible })), (action.detail.status.hasInteracted !== undefined && { hasInteracted: action.detail.status.hasInteracted })) });
37688
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_h = action.detail) === null || _h === void 0 ? void 0 : _h.timestamp, visuals: __assign$1(__assign$1(__assign$1(__assign$1(__assign$1({}, (state.visuals || {})), (action.detail.status.drawer !== undefined && { drawer: action.detail.status.drawer })), (action.detail.status.opened !== undefined && { opened: action.detail.status.opened })), (action.detail.status.visible !== undefined && { visible: action.detail.status.visible })), (action.detail.status.hasInteracted !== undefined && { hasInteracted: action.detail.status.hasInteracted })) });
37467
37689
  case "toggle_debug_mode":
37468
37690
  var newDebugMode = !state.debugMode;
37469
37691
  // Update localStorage to persist the setting
37470
37692
  if (typeof window !== 'undefined' && window.localStorage) {
37471
37693
  window.localStorage.setItem('xaErrorOverlay', newDebugMode ? 'enabled' : 'disabled');
37472
37694
  }
37473
- return __assign(__assign({}, state), { debugMode: newDebugMode });
37695
+ return __assign$1(__assign$1({}, state), { debugMode: newDebugMode });
37474
37696
  case "ws_button_display":
37475
- return __assign(__assign({}, state), { lastTimestamp: (_j = action.detail) === null || _j === void 0 ? void 0 : _j.timestamp, wsButton: {
37697
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_j = action.detail) === null || _j === void 0 ? void 0 : _j.timestamp, wsButton: {
37476
37698
  id: action.detail.id,
37477
37699
  // Preserve existing text if new text is empty (e.g., during dismiss animation)
37478
37700
  text: action.detail.text || ((_k = state.wsButton) === null || _k === void 0 ? void 0 : _k.text) || '',
@@ -37483,19 +37705,19 @@ function update(state, action) {
37483
37705
  case "ws_button_dismiss":
37484
37706
  // Only dismiss if the id matches
37485
37707
  if (((_o = state.wsButton) === null || _o === void 0 ? void 0 : _o.id) === action.detail.id) {
37486
- return __assign(__assign({}, state), { lastTimestamp: (_p = action.detail) === null || _p === void 0 ? void 0 : _p.timestamp, wsButton: undefined });
37708
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_p = action.detail) === null || _p === void 0 ? void 0 : _p.timestamp, wsButton: undefined });
37487
37709
  }
37488
37710
  return state;
37489
37711
  case "department_update":
37490
- return __assign(__assign({}, state), { lastTimestamp: (_q = action.detail) === null || _q === void 0 ? void 0 : _q.timestamp, departments: __assign(__assign({}, state.departments), (_a = {}, _a[action.detail.id] = __assign({}, action.detail), _a)) });
37712
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_q = action.detail) === null || _q === void 0 ? void 0 : _q.timestamp, departments: __assign$1(__assign$1({}, state.departments), (_a = {}, _a[action.detail.id] = __assign$1({}, action.detail), _a)) });
37491
37713
  case "visitor_update":
37492
- return __assign(__assign({}, state), { lastTimestamp: (_r = action.detail) === null || _r === void 0 ? void 0 : _r.timestamp, visitor: __assign(__assign({}, state.visitor), action.detail) });
37714
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_r = action.detail) === null || _r === void 0 ? void 0 : _r.timestamp, visitor: __assign$1(__assign$1({}, state.visitor), action.detail) });
37493
37715
  case "agent_update":
37494
37716
  var prevUpdateAgent = state.agents[action.detail.nick];
37495
- return __assign(__assign({}, state), { lastTimestamp: (_s = action.detail) === null || _s === void 0 ? void 0 : _s.timestamp, agents: __assign(__assign({}, state.agents), (_b = {}, _b[action.detail.nick] = __assign(__assign({}, prevUpdateAgent), { user: __assign(__assign({}, prevUpdateAgent.user), action.detail), typing: (prevUpdateAgent || { typing: false }).typing // if we had it - keep it
37717
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_s = action.detail) === null || _s === void 0 ? void 0 : _s.timestamp, agents: __assign$1(__assign$1({}, state.agents), (_b = {}, _b[action.detail.nick] = __assign$1(__assign$1({}, prevUpdateAgent), { user: __assign$1(__assign$1({}, prevUpdateAgent.user), action.detail), typing: (prevUpdateAgent || { typing: false }).typing // if we had it - keep it
37496
37718
  }), _b)) });
37497
37719
  case "chat":
37498
- var newState = __assign(__assign({}, state), { lastTimestamp: (_t = action.detail) === null || _t === void 0 ? void 0 : _t.timestamp });
37720
+ var newState = __assign$1(__assign$1({}, state), { lastTimestamp: (_t = action.detail) === null || _t === void 0 ? void 0 : _t.timestamp });
37499
37721
  switch (action.detail.type) {
37500
37722
  case "chat.memberjoin":
37501
37723
  return memberJoin(state, action.detail);
@@ -37508,7 +37730,7 @@ function update(state, action) {
37508
37730
  case "chat.systemmessagedismiss":
37509
37731
  // Remove system message(s) with the specified id
37510
37732
  var dismissId_1 = action.detail.id;
37511
- return __assign(__assign({}, newState), { chats: newState.chats.filter(function (chat) {
37733
+ return __assign$1(__assign$1({}, newState), { chats: newState.chats.filter(function (chat) {
37512
37734
  // Keep all non-system messages, and system messages that don't match the id
37513
37735
  if (isChatSystemMessage(chat)) {
37514
37736
  return chat.id !== dismissId_1;
@@ -37520,10 +37742,10 @@ function update(state, action) {
37520
37742
  return newState;
37521
37743
  case "chat.request.rating":
37522
37744
  appendMessageToState(newState, action.detail);
37523
- return __assign(__assign({}, newState), { lastRatingRequestTimestamp: action.detail.timestamp });
37745
+ return __assign$1(__assign$1({}, newState), { lastRatingRequestTimestamp: action.detail.timestamp });
37524
37746
  case "chat.rating":
37525
37747
  appendMessageToState(newState, action.detail);
37526
- return __assign(__assign({}, newState), { hasRating: !!action.detail.newRating });
37748
+ return __assign$1(__assign$1({}, newState), { hasRating: !!action.detail.newRating });
37527
37749
  case "chat.file":
37528
37750
  case "chat.msg":
37529
37751
  appendMessageToState(newState, action.detail);
@@ -37543,19 +37765,19 @@ function update(state, action) {
37543
37765
  var clearedChats = newState.chats.filter(function (item) {
37544
37766
  return item !== oldFailureMsg_1;
37545
37767
  });
37546
- finalState = __assign(__assign({}, newState), { chats: clearedChats });
37768
+ finalState = __assign$1(__assign$1({}, newState), { chats: clearedChats });
37547
37769
  }
37548
37770
  appendMessageToState(finalState, action.detail);
37549
- return __assign(__assign({}, finalState), { agents: __assign(__assign({}, finalState.agents), (_c = {}, _c[action.detail.user.nick] = __assign(__assign({}, agentDetails), { typing: false, requestFailed: true }), _c)), failureMsg: action.detail.failureMsg });
37771
+ return __assign$1(__assign$1({}, finalState), { agents: __assign$1(__assign$1({}, finalState.agents), (_c = {}, _c[action.detail.user.nick] = __assign$1(__assign$1({}, agentDetails), { typing: false, requestFailed: true }), _c)), failureMsg: action.detail.failureMsg });
37550
37772
  case "chat.typing":
37551
37773
  var agent = state.agents[action.detail.user.nick];
37552
- return __assign(__assign({}, state), { lastTimestamp: (_v = action.detail) === null || _v === void 0 ? void 0 : _v.timestamp, agents: __assign(__assign({}, state.agents), (_d = {}, _d[action.detail.user.nick] = __assign(__assign({}, agent), { typing: action.detail.typing }), _d)) });
37774
+ return __assign$1(__assign$1({}, state), { lastTimestamp: (_v = action.detail) === null || _v === void 0 ? void 0 : _v.timestamp, agents: __assign$1(__assign$1({}, state.agents), (_d = {}, _d[action.detail.user.nick] = __assign$1(__assign$1({}, agent), { typing: action.detail.typing }), _d)) });
37553
37775
  case "chat.stream.start": {
37554
37776
  // Clean up any orphan streaming messages from interrupted streams
37555
37777
  // before creating the new placeholder.
37556
37778
  var cleanedChats = newState.chats.map(function (chat) {
37557
37779
  if (isChatMsgDetail(chat) && chat.isStreaming) {
37558
- return __assign(__assign({}, chat), { isStreaming: false, wasStreamed: true });
37780
+ return __assign$1(__assign$1({}, chat), { isStreaming: false, wasStreamed: true });
37559
37781
  }
37560
37782
  return chat;
37561
37783
  });
@@ -37573,7 +37795,7 @@ function update(state, action) {
37573
37795
  isStreaming: true,
37574
37796
  };
37575
37797
  var newChats = joinMessages(cleanedChats, streamingMsg);
37576
- return __assign(__assign({}, newState), { chats: newChats, streamingMessageId: action.detail.messageId });
37798
+ return __assign$1(__assign$1({}, newState), { chats: newChats, streamingMessageId: action.detail.messageId });
37577
37799
  }
37578
37800
  case "chat.stream.chunk": {
37579
37801
  // Find the streaming message by ID and append text
@@ -37583,10 +37805,10 @@ function update(state, action) {
37583
37805
  var streamingIndex_1 = findLastStreamingIndex(state.chats);
37584
37806
  if (streamingIndex_1 >= 0) {
37585
37807
  var chunkText_1 = chunkDetail.text;
37586
- return __assign(__assign({}, state), { lastTimestamp: chunkDetail === null || chunkDetail === void 0 ? void 0 : chunkDetail.timestamp, chats: state.chats.map(function (chat, index) {
37808
+ return __assign$1(__assign$1({}, state), { lastTimestamp: chunkDetail === null || chunkDetail === void 0 ? void 0 : chunkDetail.timestamp, chats: state.chats.map(function (chat, index) {
37587
37809
  var _a;
37588
37810
  if (index === streamingIndex_1 && isChatMsgDetail(chat)) {
37589
- return __assign(__assign({}, chat), { msg: __assign(__assign({}, chat.msg), { text: (((_a = chat.msg) === null || _a === void 0 ? void 0 : _a.text) || "") + chunkText_1 }) });
37811
+ return __assign$1(__assign$1({}, chat), { msg: __assign$1(__assign$1({}, chat.msg), { text: (((_a = chat.msg) === null || _a === void 0 ? void 0 : _a.text) || "") + chunkText_1 }) });
37590
37812
  }
37591
37813
  return chat;
37592
37814
  }) });
@@ -37602,10 +37824,10 @@ function update(state, action) {
37602
37824
  // Find the streaming message by ID (not by index - other messages could be inserted)
37603
37825
  var streamingIndex_2 = findLastStreamingIndex(state.chats);
37604
37826
  if (streamingIndex_2 >= 0) {
37605
- return __assign(__assign({}, state), { lastTimestamp: toolStartDetail_1.timestamp, chats: state.chats.map(function (chat, index) {
37827
+ return __assign$1(__assign$1({}, state), { lastTimestamp: toolStartDetail_1.timestamp, chats: state.chats.map(function (chat, index) {
37606
37828
  if (index === streamingIndex_2 && isChatMsgDetail(chat)) {
37607
37829
  var existingToolCalls = chat.toolCalls || [];
37608
- return __assign(__assign({}, chat), { toolCalls: __spreadArray$1(__spreadArray$1([], existingToolCalls, true), [
37830
+ return __assign$1(__assign$1({}, chat), { toolCalls: __spreadArray$1(__spreadArray$1([], existingToolCalls, true), [
37609
37831
  {
37610
37832
  name: toolStartDetail_1.toolName,
37611
37833
  toolCallId: toolStartDetail_1.toolCallId,
@@ -37632,7 +37854,7 @@ function update(state, action) {
37632
37854
  // Find the streaming message by ID (not by index - other messages could be inserted)
37633
37855
  var streamingIndex_3 = findLastStreamingIndex(state.chats);
37634
37856
  if (streamingIndex_3 >= 0) {
37635
- return __assign(__assign({}, state), { lastTimestamp: toolEndDetail_1.timestamp, chats: state.chats.map(function (chat, index) {
37857
+ return __assign$1(__assign$1({}, state), { lastTimestamp: toolEndDetail_1.timestamp, chats: state.chats.map(function (chat, index) {
37636
37858
  var _a;
37637
37859
  if (index === streamingIndex_3 && isChatMsgDetail(chat)) {
37638
37860
  var toolCalls = (_a = chat.toolCalls) === null || _a === void 0 ? void 0 : _a.map(function (tc) {
@@ -37642,11 +37864,11 @@ function update(state, action) {
37642
37864
  ? tc.toolCallId === toolEndDetail_1.toolCallId
37643
37865
  : tc.name === toolEndDetail_1.toolName && tc.isExecuting;
37644
37866
  if (isMatch) {
37645
- return __assign(__assign({}, tc), { displayName: toolEndDetail_1.displayName || tc.displayName, label: toolEndDetail_1.label, hidden: (_a = toolEndDetail_1.hidden) !== null && _a !== void 0 ? _a : tc.hidden, input: (_b = toolEndDetail_1.toolInput) !== null && _b !== void 0 ? _b : tc.input, result: toolEndDetail_1.toolResult, error: toolEndDetail_1.toolError, endTime: toolEndDetail_1.timestamp, isExecuting: false });
37867
+ return __assign$1(__assign$1({}, tc), { displayName: toolEndDetail_1.displayName || tc.displayName, label: toolEndDetail_1.label, hidden: (_a = toolEndDetail_1.hidden) !== null && _a !== void 0 ? _a : tc.hidden, input: (_b = toolEndDetail_1.toolInput) !== null && _b !== void 0 ? _b : tc.input, result: toolEndDetail_1.toolResult, error: toolEndDetail_1.toolError, endTime: toolEndDetail_1.timestamp, isExecuting: false });
37646
37868
  }
37647
37869
  return tc;
37648
37870
  });
37649
- return __assign(__assign({}, chat), { toolCalls: toolCalls });
37871
+ return __assign$1(__assign$1({}, chat), { toolCalls: toolCalls });
37650
37872
  }
37651
37873
  return chat;
37652
37874
  }) });
@@ -37668,9 +37890,9 @@ function update(state, action) {
37668
37890
  var toolCalls_1 = endDetail.toolCalls || endStreamingChat.toolCalls;
37669
37891
  // Update chips from message options (same as chat.msg handler)
37670
37892
  var chips = ((_w = finalMsg_1 === null || finalMsg_1 === void 0 ? void 0 : finalMsg_1.options) === null || _w === void 0 ? void 0 : _w.length) ? finalMsg_1.options : [];
37671
- return __assign(__assign({}, state), { lastTimestamp: endDetail === null || endDetail === void 0 ? void 0 : endDetail.timestamp, streamingMessageId: undefined, chips: chips, chats: state.chats.map(function (chat, index) {
37893
+ return __assign$1(__assign$1({}, state), { lastTimestamp: endDetail === null || endDetail === void 0 ? void 0 : endDetail.timestamp, streamingMessageId: undefined, chips: chips, chats: state.chats.map(function (chat, index) {
37672
37894
  if (index === streamingIndex_4 && isChatMsgDetail(chat)) {
37673
- return __assign(__assign({}, chat), { msg: finalMsg_1, isStreaming: false, wasStreamed: true, toolCalls: toolCalls_1 });
37895
+ return __assign$1(__assign$1({}, chat), { msg: finalMsg_1, isStreaming: false, wasStreamed: true, toolCalls: toolCalls_1 });
37674
37896
  }
37675
37897
  return chat;
37676
37898
  }) });
@@ -37685,9 +37907,9 @@ function update(state, action) {
37685
37907
  if (state.streamingMessageId === abortDetail.messageId) {
37686
37908
  var streamingIndex_5 = findLastStreamingIndex(state.chats);
37687
37909
  if (streamingIndex_5 >= 0) {
37688
- return __assign(__assign({}, state), { lastTimestamp: abortDetail.timestamp, streamingMessageId: undefined, chats: state.chats.map(function (chat, index) {
37910
+ return __assign$1(__assign$1({}, state), { lastTimestamp: abortDetail.timestamp, streamingMessageId: undefined, chats: state.chats.map(function (chat, index) {
37689
37911
  if (index === streamingIndex_5 && isChatMsgDetail(chat)) {
37690
- return __assign(__assign({}, chat), { isStreaming: false, wasStreamed: true });
37912
+ return __assign$1(__assign$1({}, chat), { isStreaming: false, wasStreamed: true });
37691
37913
  }
37692
37914
  return chat;
37693
37915
  }) });
@@ -37714,9 +37936,9 @@ function update(state, action) {
37714
37936
  }
37715
37937
  }
37716
37938
  if (lastBotIndex_1 >= 0) {
37717
- return __assign(__assign({}, state), { lastTimestamp: resumeDetail.timestamp, streamingMessageId: resumeDetail.messageId, chats: state.chats.map(function (chat, index) {
37939
+ return __assign$1(__assign$1({}, state), { lastTimestamp: resumeDetail.timestamp, streamingMessageId: resumeDetail.messageId, chats: state.chats.map(function (chat, index) {
37718
37940
  if (index === lastBotIndex_1 && isChatMsgDetail(chat)) {
37719
- return __assign(__assign({}, chat), { isStreaming: true, wasStreamed: false });
37941
+ return __assign$1(__assign$1({}, chat), { isStreaming: true, wasStreamed: false });
37720
37942
  }
37721
37943
  return chat;
37722
37944
  }) });
@@ -37868,8 +38090,8 @@ function generateKey(connection, sessionId) {
37868
38090
  */
37869
38091
  var ChatWidgetPreviewContainer = function (props) {
37870
38092
  var messageMiddleware = useStandardMiddleware();
37871
- var widgetProps = __assign(__assign({}, props), { messageMiddleware: messageMiddleware });
37872
- return jsx(ChatWidgetWrapper, __assign({}, widgetProps));
38093
+ var widgetProps = __assign$1(__assign$1({}, props), { messageMiddleware: messageMiddleware });
38094
+ return jsx(ChatWidgetWrapper, __assign$1({}, widgetProps));
37873
38095
  };
37874
38096
  /**
37875
38097
  * Connected mode container - creates store and connects to server.
@@ -37892,9 +38114,9 @@ var ChatWidgetConnectedContainer = function (props) {
37892
38114
  if ((_f = props.config) === null || _f === void 0 ? void 0 : _f.disabled) {
37893
38115
  return jsx(Fragment, {});
37894
38116
  }
37895
- var widgetProps = __assign(__assign({}, props), { messageMiddleware: messageMiddleware, getConfig: props.getConfig // Pass through getConfig callback
38117
+ var widgetProps = __assign$1(__assign$1({}, props), { messageMiddleware: messageMiddleware, getConfig: props.getConfig // Pass through getConfig callback
37896
38118
  });
37897
- return (jsx(Provider, { store: chatStore, children: jsx(ChatWidgetWrapper, __assign({}, widgetProps)) }));
38119
+ return (jsx(Provider, { store: chatStore, children: jsx(ChatWidgetWrapper, __assign$1({}, widgetProps)) }));
37898
38120
  };
37899
38121
  /**
37900
38122
  * Top-level container that dispatches between preview and connected modes.
@@ -37905,9 +38127,9 @@ var ChatWidgetContainer = function (props) {
37905
38127
  // Support both `preview` prop and legacy `mode="preview"`
37906
38128
  var isPreviewMode = props.preview === true || rawMode === "preview";
37907
38129
  if (isPreviewMode) {
37908
- return jsx(ChatWidgetPreviewContainer, __assign({}, props));
38130
+ return jsx(ChatWidgetPreviewContainer, __assign$1({}, props));
37909
38131
  }
37910
- return jsx(ChatWidgetConnectedContainer, __assign({}, props));
38132
+ return jsx(ChatWidgetConnectedContainer, __assign$1({}, props));
37911
38133
  };
37912
38134
 
37913
38135
  var isActionBarChatButton$1 = lib.isActionBarChatButton;