@eshal-bot/chat-widget 0.1.41 → 0.1.42

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.
@@ -8582,31 +8582,34 @@
8582
8582
  };
8583
8583
 
8584
8584
  /**
8585
- * Constructs the WebSocket URL.
8586
- * @param {string} apiBaseUrl - The base URL of the API (used when wsBaseUrl is not provided).
8587
- * @param {string} [wsBaseUrl] - Explicit WebSocket base URL (e.g. wss://knowledge-api-prod.eshal.ai/ws).
8588
- * When provided, it is returned directly without any transformation.
8589
- * @returns {string} The WebSocket base URL.
8585
+ * Constructs the voice WebSocket base URL — ALWAYS derived from the API
8586
+ * base URL the widget is embedded with, as `wss://{host}/voice/ws`.
8587
+ *
8588
+ * `/voice/ws/{org}/{session}` is terminated by the frontend custom server
8589
+ * (packages/frontend/server.js), which proxies it in-cluster to
8590
+ * knowledge-api on `/ws`. The widget always talks to the same origin it
8591
+ * loaded its config from, so the WS endpoint is fully determined by
8592
+ * `apiBaseUrl`. There is intentionally NO override parameter: voice can
8593
+ * never be pointed at the (no-longer-public) knowledge-api LoadBalancer by
8594
+ * a stale embed option or backend config value.
8595
+ *
8596
+ * @param {string} apiBaseUrl - Frontend base URL, e.g. https://demo.eshal.ai
8597
+ * @returns {string} Voice WS base, e.g. wss://demo.eshal.ai/voice/ws
8590
8598
  */
8591
- const getWebSocketUrl = (apiBaseUrl, wsBaseUrl) => {
8592
- if (wsBaseUrl) {
8593
- return wsBaseUrl.replace(/\/$/, '');
8594
- }
8599
+ const getWebSocketUrl = apiBaseUrl => {
8595
8600
  if (!apiBaseUrl) {
8596
- // Default fallback if no API base URL is provided
8601
+ // No base URL yet (config still loading) safe public default.
8597
8602
  return 'wss://dev.eshal.ai/voice/ws';
8598
8603
  }
8599
8604
  try {
8600
8605
  const url = new URL(apiBaseUrl);
8601
- // Replace http/https with ws/wss
8606
+ // http→ws, https→wss; point at the frontend voice-proxy path.
8602
8607
  url.protocol = url.protocol.replace(/^http/, 'ws');
8603
- // Append the WebSocket specific path
8604
8608
  url.pathname = '/voice/ws';
8605
- // Ensure it returns a clean URL without extra slashes
8609
+ // Clean URL without a trailing slash.
8606
8610
  return url.toString().replace(/\/$/, '');
8607
8611
  } catch (error) {
8608
8612
  console.error("Invalid API base URL provided for WebSocket:", error);
8609
- // Fallback to default if URL parsing fails
8610
8613
  return 'wss://dev.eshal.ai/voice/ws';
8611
8614
  }
8612
8615
  };
@@ -8926,7 +8929,6 @@
8926
8929
  welcomeMessage,
8927
8930
  quickQuestions = [],
8928
8931
  apiBaseUrl,
8929
- wsBaseUrl,
8930
8932
  apiKey,
8931
8933
  organizationId,
8932
8934
  autoOpen,
@@ -9077,8 +9079,9 @@
9077
9079
  const visitorProfileRef = reactExports.useRef(null);
9078
9080
  const websocketUrl = reactExports.useMemo(() => {
9079
9081
  if (!organizationId) return null;
9080
- // Construct WebSocket URL from the API base URL
9081
- const resolvedWsBaseUrl = getWebSocketUrl(apiBaseUrl, wsBaseUrl);
9082
+ // Voice WS base is always derived from apiBaseUrl (the frontend origin
9083
+ // the widget is embedded with) → wss://{host}/voice/ws. No override.
9084
+ const resolvedWsBaseUrl = getWebSocketUrl(apiBaseUrl);
9082
9085
  return "".concat(resolvedWsBaseUrl, "/").concat(organizationId, "/").concat(bidiSessionId);
9083
9086
  }, [apiBaseUrl, organizationId, bidiSessionId]);
9084
9087
  const getNextMessageId = reactExports.useCallback(() => {
@@ -31823,7 +31826,7 @@
31823
31826
  if (typeof document === 'undefined') {
31824
31827
  return null;
31825
31828
  }
31826
- if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
31829
+ if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
31827
31830
  return /** @type {any} */document.currentScript;
31828
31831
  }
31829
31832
 
@@ -60383,7 +60386,6 @@
60383
60386
  // Required props for dynamic config
60384
60387
  orgId,
60385
60388
  apiBaseUrl,
60386
- wsBaseUrl,
60387
60389
  // Optional override props (will override fetched config if provided)
60388
60390
  darkMode,
60389
60391
  primaryColor,
@@ -60566,7 +60568,6 @@
60566
60568
  welcomeMessage: "Hi! How can we help?",
60567
60569
  quickQuestions: [],
60568
60570
  apiBaseUrl: apiBaseUrl || "",
60569
- wsBaseUrl: agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.wsBaseUrl,
60570
60571
  apiKey: apiKey || "",
60571
60572
  organizationId: orgId || "",
60572
60573
  autoOpen: false,
@@ -60576,7 +60577,7 @@
60576
60577
  onboardingQuestions: [],
60577
60578
  onboardingEnabled: false,
60578
60579
  collectionPrompt: undefined
60579
- }), [apiBaseUrl, wsBaseUrl, apiKey, orgId]);
60580
+ }), [apiBaseUrl, apiKey, orgId]);
60580
60581
 
60581
60582
  // ALWAYS call hooks before any early returns (Rules of Hooks)
60582
60583
  const {
@@ -60617,7 +60618,11 @@
60617
60618
  welcomeMessage: widgetConfig.welcomeMessage,
60618
60619
  quickQuestions: widgetConfig.quickQuestions,
60619
60620
  apiBaseUrl,
60620
- wsBaseUrl: agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.wsBaseUrl,
60621
+ // Voice WS endpoint is derived entirely from apiBaseUrl inside
60622
+ // useChatState (→ wss://{host}/voice/ws, the frontend voice proxy).
60623
+ // Nothing is forwarded/overridable here, so a stale backend or embed
60624
+ // wsBaseUrl can't point voice at the old (now non-public)
60625
+ // knowledge-api LoadBalancer.
60621
60626
  apiKey,
60622
60627
  organizationId: widgetConfig.organizationId,
60623
60628
  autoOpen,