@eshal-bot/chat-widget 0.1.100 → 0.1.102

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.
@@ -1 +1 @@
1
- export{S as default}from"./chat-widget-index-BOARafNH.esm.js";import"react";import"react-dom/client";import"react-dom";import"react/jsx-runtime";
1
+ export{S as default}from"./chat-widget-index-BcPgyNKZ.esm.js";import"react";import"react-dom/client";import"react-dom";import"react/jsx-runtime";
@@ -8183,6 +8183,10 @@
8183
8183
  // (the full follow-up question) on click. Kept here or it's whitelisted
8184
8184
  // out before render; click handlers fall back to `text` when absent.
8185
8185
  submitText: typeof p.submitText === 'string' ? p.submitText : undefined,
8186
+ // EV-2979: the server mints a per-chip promptId so click rows can
8187
+ // be joined to their impression row. This whitelist would strip it
8188
+ // otherwise. Optional - older payloads simply have none.
8189
+ promptId: typeof p.promptId === 'string' ? p.promptId : undefined,
8186
8190
  confidence: typeof p.confidence === 'number' ? p.confidence : undefined
8187
8191
  })).filter(p => p.text);
8188
8192
  return normalized.length ? normalized : undefined;
@@ -8968,6 +8972,34 @@
8968
8972
  return classes.filter(Boolean).join(' ');
8969
8973
  };
8970
8974
 
8975
+ /**
8976
+ * EV-2977: what an auto-prompt chip DISPLAYS.
8977
+ *
8978
+ * Each auto-prompt has a dual output: `text` (short title-case label,
8979
+ * e.g. "Geidea Accept Payments") and `submitText` (the full natural
8980
+ * question, e.g. "How do I accept payments?") which is what actually
8981
+ * gets submitted on click. Product decision: the web widget shows the
8982
+ * natural question (Perplexity/ChatGPT-style follow-ups) instead of
8983
+ * the label. Display-only - the SUBMIT value and the prompt payload
8984
+ * (`text`, `submitText`) are untouched.
8985
+ *
8986
+ * Kill-switch: `behavior.autoPromptQuestionDisplay` (default true).
8987
+ * When false - or when `submitText` is absent/identical - falls back
8988
+ * to the label, i.e. the pre-EV-2977 rendering.
8989
+ *
8990
+ * @param {{text?: string, submitText?: string}|string} prompt
8991
+ * @param {boolean} [questionDisplay=true]
8992
+ * @returns {string}
8993
+ */
8994
+ const getPromptDisplayText = function (prompt) {
8995
+ let questionDisplay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
8996
+ if (!prompt || typeof prompt === 'string') return prompt || '';
8997
+ const label = typeof prompt.text === 'string' ? prompt.text : '';
8998
+ if (!questionDisplay) return label;
8999
+ const question = typeof prompt.submitText === 'string' ? prompt.submitText.trim() : '';
9000
+ return question && question !== label ? question : label;
9001
+ };
9002
+
8971
9003
  /**
8972
9004
  * Constructs the voice WebSocket base URL.
8973
9005
  *
@@ -17152,7 +17184,11 @@
17152
17184
  promptFontSize,
17153
17185
  isDark,
17154
17186
  isRtl,
17155
- t
17187
+ t,
17188
+ // EV-2977: show the natural question (submitText) on the chip face
17189
+ // instead of the title-case label. Display-only; see
17190
+ // getPromptDisplayText. Kill-switch: behavior.autoPromptQuestionDisplay.
17191
+ questionDisplay = true
17156
17192
  } = _ref;
17157
17193
  const scrollRef = reactExports.useRef(null);
17158
17194
  const [canScrollLeft, setCanScrollLeft] = reactExports.useState(false);
@@ -17235,7 +17271,7 @@
17235
17271
  fontFamily: promptFontFamily,
17236
17272
  fontSize: promptFontSize
17237
17273
  },
17238
- children: p.text || p
17274
+ children: getPromptDisplayText(p, questionDisplay)
17239
17275
  }, "".concat(p.text || p, "-").concat(index)))
17240
17276
  }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
17241
17277
  type: "button",
@@ -17297,6 +17333,10 @@
17297
17333
  userTextColor,
17298
17334
  promptSuggestions,
17299
17335
  onPromptSuggestionClick,
17336
+ // EV-2977: chip face shows the natural question (submitText) instead
17337
+ // of the title-case label. Kill-switch per deployment via
17338
+ // behavior.autoPromptQuestionDisplay; default on.
17339
+ autoPromptQuestionDisplay = true,
17300
17340
  // Inline tag selector, rendered at the top of the input card in the
17301
17341
  // same slot as PromptSuggestionsRow. Mutually exclusive with prompt
17302
17342
  // suggestions in practice (tag selector only shows before the user
@@ -17580,6 +17620,7 @@
17580
17620
  children: [tagSelectorNode ? tagSelectorNode : promptSuggestions.length > 0 && onPromptSuggestionClick && /*#__PURE__*/jsxRuntimeExports.jsx(PromptSuggestionsRow, {
17581
17621
  suggestions: promptSuggestions,
17582
17622
  onSuggestionClick: onPromptSuggestionClick,
17623
+ questionDisplay: autoPromptQuestionDisplay,
17583
17624
  promptPrimary: promptPrimary,
17584
17625
  promptTextColor: promptTextColor,
17585
17626
  promptFontFamily: promptFontFamily,
@@ -18762,6 +18803,162 @@
18762
18803
  });
18763
18804
  };
18764
18805
 
18806
+ /**
18807
+ * EV-2979 - auto-prompt chip CLICK telemetry (client half).
18808
+ *
18809
+ * Impressions are logged server-side at the chip-generation call sites;
18810
+ * clicks can only be observed on the client, so this module is the last
18811
+ * link in the funnel. It posts to the Express support proxy at
18812
+ * `POST /api/v1/support/chip-click`, which re-derives the organization
18813
+ * from the verified widget auth (EV-2388 - the client MUST NOT send an
18814
+ * organizationId) and forwards to knowledge-api.
18815
+ *
18816
+ * Hard rules, in priority order over "did the event land":
18817
+ * 1. Never block, delay or break the chip's real action. Callers must
18818
+ * not await this; every failure path resolves to `false` and never
18819
+ * throws.
18820
+ * 2. Never send PII beyond what the chip itself already contains
18821
+ * (its label, its submit text, its position, the conversation id).
18822
+ * 3. Be a silent no-op when there is nothing safe to send: no API base
18823
+ * URL, no conversation id, or telemetry disabled by config.
18824
+ *
18825
+ * Transport: `navigator.sendBeacon` is preferred because the browser
18826
+ * keeps it in flight across the re-render (and even a navigation) that
18827
+ * a chip click triggers. sendBeacon cannot set request headers, so the
18828
+ * in-app Bearer path (`getAuthToken` present, i.e. session auth) falls
18829
+ * back to `fetch(..., { keepalive: true })`, which has the same
18830
+ * survive-the-unload property but can carry Authorization. Mode B
18831
+ * embeds have no token - the HMAC signature is added by the
18832
+ * @eshal-bot/server proxy - so those take the sendBeacon path.
18833
+ */
18834
+
18835
+ const CHIP_CLICK_PATH = '/api/v1/support/chip-click';
18836
+
18837
+ /**
18838
+ * Builds the wire payload for a chip click.
18839
+ *
18840
+ * `chipText` is deliberately the chip's SHORT LABEL (`text`), not the
18841
+ * displayed question (`submitText`): impression rows store `chip_text`
18842
+ * from `text`, so using the label is what makes clicks joinable to
18843
+ * impressions. EV-2977 changed only what the chip DISPLAYS.
18844
+ *
18845
+ * @param {{chip?: object|string, submitText?: string, position?: number,
18846
+ * conversationId?: string, source?: string}} args
18847
+ * @returns {object|null} payload, or null when there is no usable chipText
18848
+ */
18849
+ function buildChipClickPayload() {
18850
+ let {
18851
+ chip,
18852
+ submitText,
18853
+ position,
18854
+ conversationId,
18855
+ source = 'widget'
18856
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18857
+ const isObject = chip && typeof chip === 'object';
18858
+ const label = isObject && typeof chip.text === 'string' ? chip.text : '';
18859
+ const submit = typeof submitText === 'string' && submitText ? submitText : isObject && typeof chip.submitText === 'string' ? chip.submitText : typeof chip === 'string' ? chip : '';
18860
+ const chipText = label || submit;
18861
+ if (!chipText) return null;
18862
+ const payload = {
18863
+ conversationId,
18864
+ chipText,
18865
+ submitText: submit || undefined,
18866
+ position: Number.isInteger(position) ? position : undefined,
18867
+ source
18868
+ };
18869
+
18870
+ // The chip payload is growing a `promptId` concurrently. Read it
18871
+ // defensively and simply omit the key until it exists - this must
18872
+ // never become a hard dependency.
18873
+ const promptId = isObject ? chip === null || chip === void 0 ? void 0 : chip.promptId : undefined;
18874
+ if (typeof promptId === 'string' && promptId) payload.promptId = promptId;
18875
+ return payload;
18876
+ }
18877
+
18878
+ /**
18879
+ * Fire-and-forget chip-click beacon.
18880
+ *
18881
+ * @param {object} args
18882
+ * @param {string} [args.apiBaseUrl] Support API base (same one /csat uses).
18883
+ * @param {string} [args.conversationId] Required; no conversation = no event.
18884
+ * @param {object|string} [args.chip] The chip object from the suggestions row.
18885
+ * @param {string} [args.submitText] What the click submits.
18886
+ * @param {number} [args.position] 0-based index within the strip.
18887
+ * @param {string} [args.source] Surface id, defaults to "widget".
18888
+ * @param {Function} [args.getAuthToken] Optional async () => token (in-app path).
18889
+ * @param {boolean} [args.enabled] Config kill-switch, defaults to true.
18890
+ * @returns {Promise<boolean>} true only if a request was actually dispatched.
18891
+ */
18892
+ async function sendChipClickBeacon() {
18893
+ let {
18894
+ apiBaseUrl,
18895
+ conversationId,
18896
+ chip,
18897
+ submitText,
18898
+ position,
18899
+ source = 'widget',
18900
+ getAuthToken,
18901
+ enabled = true
18902
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18903
+ try {
18904
+ if (enabled === false) return false;
18905
+ if (!apiBaseUrl || typeof apiBaseUrl !== 'string') return false;
18906
+ if (!conversationId || typeof conversationId !== 'string') return false;
18907
+ const payload = buildChipClickPayload({
18908
+ chip,
18909
+ submitText,
18910
+ position,
18911
+ conversationId,
18912
+ source
18913
+ });
18914
+ if (!payload) return false;
18915
+ const url = "".concat(apiBaseUrl.replace(/\/$/, '')).concat(CHIP_CLICK_PATH);
18916
+ const body = JSON.stringify(payload);
18917
+ let token;
18918
+ if (typeof getAuthToken === 'function') {
18919
+ try {
18920
+ token = await getAuthToken();
18921
+ } catch (_unused) {
18922
+ token = undefined;
18923
+ }
18924
+ }
18925
+
18926
+ // No Authorization header needed -> sendBeacon, the most
18927
+ // re-render/unload-proof transport available.
18928
+ if (!token && typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function' && typeof Blob !== 'undefined') {
18929
+ try {
18930
+ const queued = navigator.sendBeacon(url, new Blob([body], {
18931
+ type: 'application/json'
18932
+ }));
18933
+ if (queued) return true;
18934
+ // sendBeacon returns false when the user agent refuses to queue
18935
+ // (payload over the per-origin budget); fall through to fetch.
18936
+ } catch (_unused2) {
18937
+ // Fall through to fetch.
18938
+ }
18939
+ }
18940
+ if (typeof fetch !== 'function') return false;
18941
+ const headers = {
18942
+ 'Content-Type': 'application/json'
18943
+ };
18944
+ if (token) headers.Authorization = "Bearer ".concat(token);
18945
+
18946
+ // Not awaited by callers; keepalive keeps it alive past the
18947
+ // re-render the click causes.
18948
+ await fetch(url, {
18949
+ method: 'POST',
18950
+ headers,
18951
+ credentials: 'include',
18952
+ keepalive: true,
18953
+ body
18954
+ });
18955
+ return true;
18956
+ } catch (_unused3) {
18957
+ // Telemetry only - never surface to the user, never rethrow.
18958
+ return false;
18959
+ }
18960
+ }
18961
+
18765
18962
  const DEFAULT_AGENT_BUBBLE_COLOR = "#ffffff";
18766
18963
  const DEFAULT_USER_MESSAGE_COLOR = "#f5f5f5";
18767
18964
  const DEFAULT_TEXT_COLOR = "#000000";
@@ -18874,6 +19071,13 @@
18874
19071
  onboardingEnabled = false,
18875
19072
  onResetConversation,
18876
19073
  autoPromptEnabled = true,
19074
+ // EV-2977: auto-prompt chips display the natural question
19075
+ // (submitText) instead of the title-case label. Display-only;
19076
+ // kill-switch via behavior.autoPromptQuestionDisplay (default on).
19077
+ autoPromptQuestionDisplay = true,
19078
+ // EV-2979: fire-and-forget click telemetry for auto-prompt chips.
19079
+ // Kill-switch via behavior.autoPromptClickTelemetry (default on).
19080
+ autoPromptClickTelemetry = true,
18877
19081
  allowFeedback = true,
18878
19082
  provideCitations = true,
18879
19083
  onFeedback,
@@ -18910,37 +19114,23 @@
18910
19114
  (_panelRef$current = panelRef.current) === null || _panelRef$current === void 0 || _panelRef$current.focus();
18911
19115
  }, []);
18912
19116
 
18913
- // EV-2842 - chip click telemetry. Fire-and-forget POST to the
18914
- // HMAC-verified support proxy (same auth pattern as the CSAT calls
19117
+ // EV-2842 / EV-2979 - chip click telemetry. Fire-and-forget POST to
19118
+ // the verified support proxy (same auth pattern as the CSAT calls
18915
19119
  // below). A telemetry failure must never block or delay submitting
18916
- // the chip's text, so this is never awaited and swallows everything.
18917
- const reportChipClick = reactExports.useCallback(async (submitValue, prompt, index) => {
18918
- try {
18919
- if (!apiBaseUrl) return;
18920
- const headers = {
18921
- "Content-Type": "application/json"
18922
- };
18923
- if (typeof getAuthToken === "function") {
18924
- const token = await getAuthToken();
18925
- if (token) headers["Authorization"] = "Bearer ".concat(token);
18926
- }
18927
- await fetch("".concat(apiBaseUrl.replace(/\/$/, ""), "/api/v1/support/chip-click"), {
18928
- method: "POST",
18929
- headers,
18930
- credentials: "include",
18931
- keepalive: true,
18932
- body: JSON.stringify({
18933
- conversationId,
18934
- chipText: prompt && prompt.text || String(submitValue !== null && submitValue !== void 0 ? submitValue : ""),
18935
- submitText: String(submitValue !== null && submitValue !== void 0 ? submitValue : ""),
18936
- position: Number.isInteger(index) ? index : undefined,
18937
- source: "widget"
18938
- })
18939
- });
18940
- } catch (_unused) {
18941
- // Telemetry only - never surface to the user.
18942
- }
18943
- }, [apiBaseUrl, getAuthToken, conversationId]);
19120
+ // the chip's text, so this is never awaited and sendChipClickBeacon
19121
+ // swallows everything internally.
19122
+ const reportChipClick = reactExports.useCallback((submitValue, prompt, index) => {
19123
+ void sendChipClickBeacon({
19124
+ apiBaseUrl,
19125
+ conversationId,
19126
+ chip: prompt,
19127
+ submitText: submitValue == null ? undefined : String(submitValue),
19128
+ position: index,
19129
+ source: "widget",
19130
+ getAuthToken,
19131
+ enabled: autoPromptClickTelemetry
19132
+ });
19133
+ }, [apiBaseUrl, getAuthToken, conversationId, autoPromptClickTelemetry]);
18944
19134
  const stableOnPromptSuggestionClick = reactExports.useCallback((text, prompt, index) => {
18945
19135
  // EV-2842: record the chip click (not awaited). Only fires when a
18946
19136
  // prompt OBJECT rode along - i.e. a real auto-prompt chip row -
@@ -18962,7 +19152,7 @@
18962
19152
  if (!raw) return null;
18963
19153
  const parsed = JSON.parse(raw);
18964
19154
  if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.width) === "number" && typeof (parsed === null || parsed === void 0 ? void 0 : parsed.height) === "number" && parsed.width >= _WIDGET_MIN_W && parsed.height >= _WIDGET_MIN_H) return parsed;
18965
- } catch (_unused2) {/* fall through */}
19155
+ } catch (_unused) {/* fall through */}
18966
19156
  return null;
18967
19157
  });
18968
19158
  const resizeAxisRef = reactExports.useRef(null);
@@ -19010,7 +19200,7 @@
19010
19200
  if (!widgetSize) return;
19011
19201
  try {
19012
19202
  window.localStorage.setItem(_WIDGET_SIZE_KEY, JSON.stringify(widgetSize));
19013
- } catch (_unused3) {/* ignore */}
19203
+ } catch (_unused2) {/* ignore */}
19014
19204
  }, [widgetSize]);
19015
19205
  const handleResizeStart = (axis, e) => {
19016
19206
  e.preventDefault();
@@ -19038,7 +19228,7 @@
19038
19228
  try {
19039
19229
  var _getSession$csatSubmi, _getSession;
19040
19230
  return (_getSession$csatSubmi = (_getSession = getSession(organizationId)) === null || _getSession === void 0 ? void 0 : _getSession.csatSubmitted) !== null && _getSession$csatSubmi !== void 0 ? _getSession$csatSubmi : false;
19041
- } catch (_unused4) {
19231
+ } catch (_unused3) {
19042
19232
  return false;
19043
19233
  }
19044
19234
  });
@@ -19057,7 +19247,7 @@
19057
19247
  const submitted = (_getSession$csatSubmi2 = (_getSession2 = getSession(organizationId)) === null || _getSession2 === void 0 ? void 0 : _getSession2.csatSubmitted) !== null && _getSession$csatSubmi2 !== void 0 ? _getSession$csatSubmi2 : false;
19058
19248
  setCsatSubmitted(submitted);
19059
19249
  if (submitted) setShowCsat(false);
19060
- } catch (_unused5) {}
19250
+ } catch (_unused4) {}
19061
19251
  }, [conversationId]);
19062
19252
 
19063
19253
  // Auto-scroll hook
@@ -19697,6 +19887,7 @@
19697
19887
  userTextColor: userTextColor,
19698
19888
  promptSuggestions: showResolveForm || isConversationResolved || autoPromptEnabled === false || isLoading ? [] : stablePromptSuggestions,
19699
19889
  onPromptSuggestionClick: stableOnPromptSuggestionClick,
19890
+ autoPromptQuestionDisplay: autoPromptQuestionDisplay,
19700
19891
  tagSelectorNode: null,
19701
19892
  showResolveButton: isCsatEnabled && hasUserMessages && !isConversationResolved && !showResolveForm && !showCsat && !shouldHideResolveForOnboarding,
19702
19893
  onResolve: () => {
@@ -20038,7 +20229,7 @@
20038
20229
 
20039
20230
  // Map API response to widget props (use props as overrides if provided)
20040
20231
  const widgetConfig = reactExports.useMemo(() => {
20041
- var _agentConfig$config, _cfg$identity, _cfg$branding, _cfg$typography, _cfg$messages, _cfg$voice, _cfg$onboarding, _cfg$disclaimer, _cfg$csat, _cfg$inactivity, _cfg$behavior, _cfg$security, _cfg$layout, _ref2, _messages$bundles$loc, _messages$bundles, _messages$bundles$en, _messages$bundles2, _ref3, _ref4, _security$domains, _ref5, _ref6, _ref7, _branding$chatbotAvat, _branding$chatbotAvat2, _ref8, _ref9, _ref0, _ref1, _ref10, _ref11, _ref12, _ref13, _typography$headerTex, _identity$subtitle, _identity$showStatus, _identity$statusMode, _identity$officeHours, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _inactivity$timeoutVa, _inactivity$timeoutUn, _ref20, _ref21, _ref22, _ref23, _ref24, _ref25, _ref26, _ref27, _csat$enabled, _csat$format, _csat$prompt, _csat$triggerType, _csat$idleTimeoutMins, _csat$followUpEnabled, _csat$followUpPrompt, _behavior$autoPromptE, _behavior$allowFeedba, _behavior$provideCita, _agentConfig$organiza, _cfg$chatFeatures;
20232
+ var _agentConfig$config, _cfg$identity, _cfg$branding, _cfg$typography, _cfg$messages, _cfg$voice, _cfg$onboarding, _cfg$disclaimer, _cfg$csat, _cfg$inactivity, _cfg$behavior, _cfg$security, _cfg$layout, _ref2, _messages$bundles$loc, _messages$bundles, _messages$bundles$en, _messages$bundles2, _ref3, _ref4, _security$domains, _ref5, _ref6, _ref7, _branding$chatbotAvat, _branding$chatbotAvat2, _ref8, _ref9, _ref0, _ref1, _ref10, _ref11, _ref12, _ref13, _typography$headerTex, _identity$subtitle, _identity$showStatus, _identity$statusMode, _identity$officeHours, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _inactivity$timeoutVa, _inactivity$timeoutUn, _ref20, _ref21, _ref22, _ref23, _ref24, _ref25, _ref26, _ref27, _csat$enabled, _csat$format, _csat$prompt, _csat$triggerType, _csat$idleTimeoutMins, _csat$followUpEnabled, _csat$followUpPrompt, _behavior$autoPromptE, _behavior$autoPromptQ, _behavior$autoPromptC, _behavior$allowFeedba, _behavior$provideCita, _agentConfig$organiza, _cfg$chatFeatures;
20042
20233
  if (!agentConfig) {
20043
20234
  return null;
20044
20235
  }
@@ -20133,6 +20324,16 @@
20133
20324
  csatFollowUpEnabled: (_csat$followUpEnabled = csat.followUpEnabled) !== null && _csat$followUpEnabled !== void 0 ? _csat$followUpEnabled : false,
20134
20325
  csatFollowUpPrompt: (_csat$followUpPrompt = csat.followUpPrompt) !== null && _csat$followUpPrompt !== void 0 ? _csat$followUpPrompt : null,
20135
20326
  autoPromptEnabled: (_behavior$autoPromptE = behavior.autoPromptEnabled) !== null && _behavior$autoPromptE !== void 0 ? _behavior$autoPromptE : true,
20327
+ // EV-2977: chip face shows the natural follow-up question
20328
+ // (submitText) instead of the title-case label. Display-only
20329
+ // (submit payload untouched). Kill-switch per deployment: set
20330
+ // behavior.autoPromptQuestionDisplay=false to revert to labels.
20331
+ autoPromptQuestionDisplay: (_behavior$autoPromptQ = behavior.autoPromptQuestionDisplay) !== null && _behavior$autoPromptQ !== void 0 ? _behavior$autoPromptQ : true,
20332
+ // EV-2979: fire-and-forget chip-click telemetry (the click half of
20333
+ // the impression funnel). Default on; set
20334
+ // behavior.autoPromptClickTelemetry=false to silence it for a
20335
+ // deployment that does not want click events recorded.
20336
+ autoPromptClickTelemetry: (_behavior$autoPromptC = behavior.autoPromptClickTelemetry) !== null && _behavior$autoPromptC !== void 0 ? _behavior$autoPromptC : true,
20136
20337
  allowFeedback: (_behavior$allowFeedba = behavior.allowFeedback) !== null && _behavior$allowFeedba !== void 0 ? _behavior$allowFeedba : true,
20137
20338
  // behavior.provideCitations - when false, hide the Sources panel on
20138
20339
  // every message and tell the backend to skip citation generation.
@@ -20430,6 +20631,8 @@
20430
20631
  onboardingEnabled: widgetConfig.onboardingEnabled,
20431
20632
  onResetConversation: resetConversation,
20432
20633
  autoPromptEnabled: widgetConfig.autoPromptEnabled,
20634
+ autoPromptQuestionDisplay: widgetConfig.autoPromptQuestionDisplay,
20635
+ autoPromptClickTelemetry: widgetConfig.autoPromptClickTelemetry,
20433
20636
  allowFeedback: widgetConfig.allowFeedback,
20434
20637
  provideCitations: widgetConfig.provideCitations,
20435
20638
  onFeedback: handleMessageFeedback,