@hissuno/widget 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ function App() {
51
51
  | `theme` | `'light' \| 'dark' \| 'auto'` | `'light'` | Color theme (`auto` follows system preference) |
52
52
  | `userId` | `string` | - | End-user identifier for session tracking |
53
53
  | `userMetadata` | `Record<string, string>` | - | Additional user info (name, email, plan, etc.) |
54
- | `apiUrl` | `string` | `'/api/agent'` | Custom API endpoint URL |
54
+ | `apiUrl` | `string` | `'/api/integrations/widget/chat'` | Custom API endpoint URL |
55
55
  | `title` | `string` | `'Support'` | Chat window title |
56
56
  | `placeholder` | `string` | `'Ask a question...'` | Input field placeholder |
57
57
  | `initialMessage` | `string` | `'Hi! How can I help?'` | First message shown to users |
package/dist/index.d.mts CHANGED
@@ -88,8 +88,7 @@ interface HissunoWidgetProps {
88
88
  */
89
89
  userMetadata?: Record<string, string>;
90
90
  /**
91
- * The URL of your Hissuno API endpoint
92
- * @default "/api/agent"
91
+ * Optional: The URL of your Hissuno API endpoint
93
92
  */
94
93
  apiUrl?: string;
95
94
  /**
@@ -160,6 +159,13 @@ interface HissunoWidgetProps {
160
159
  * Callback when the chat window closes
161
160
  */
162
161
  onClose?: () => void;
162
+ /**
163
+ * Callback that exposes chat controls for external manipulation
164
+ * Useful for programmatically setting input values
165
+ */
166
+ onControlsReady?: (controls: {
167
+ setInput: (value: string) => void;
168
+ }) => void;
163
169
  /**
164
170
  * Additional CSS class name for custom styling
165
171
  */
@@ -232,7 +238,7 @@ interface WidgetSettings {
232
238
  * }
233
239
  * ```
234
240
  */
235
- declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
241
+ declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, onControlsReady, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
236
242
 
237
243
  interface ChatBubbleProps {
238
244
  isOpen: boolean;
@@ -275,7 +281,7 @@ interface UseHissunoChatOptions {
275
281
  projectId: string;
276
282
  /** JWT token for secure widget authentication */
277
283
  widgetToken?: string;
278
- /** Custom API endpoint URL (default: '/api/agent') */
284
+ /** Custom API endpoint URL (default: '/api/integrations/widget/chat') */
279
285
  apiUrl?: string;
280
286
  /** Initial assistant message shown when chat opens */
281
287
  initialMessage?: string;
@@ -287,6 +293,8 @@ interface UseHissunoChatOptions {
287
293
  userMetadata?: Record<string, string>;
288
294
  /** Custom session ID (auto-generated if not provided) */
289
295
  sessionId?: string;
296
+ /** Override the knowledge package used for this chat session (for testing) */
297
+ packageId?: string;
290
298
  /** Inactivity timeout in ms before auto-closing session (default: 30 minutes) */
291
299
  inactivityTimeout?: number;
292
300
  /** Callback when session is closed */
@@ -352,7 +360,7 @@ interface UseHissunoChatReturn {
352
360
  * @param options - Hook configuration options
353
361
  * @returns Chat state and control functions
354
362
  */
355
- declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
363
+ declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, packageId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
356
364
 
357
365
  interface ChatPopupProps {
358
366
  isOpen: boolean;
package/dist/index.d.ts CHANGED
@@ -88,8 +88,7 @@ interface HissunoWidgetProps {
88
88
  */
89
89
  userMetadata?: Record<string, string>;
90
90
  /**
91
- * The URL of your Hissuno API endpoint
92
- * @default "/api/agent"
91
+ * Optional: The URL of your Hissuno API endpoint
93
92
  */
94
93
  apiUrl?: string;
95
94
  /**
@@ -160,6 +159,13 @@ interface HissunoWidgetProps {
160
159
  * Callback when the chat window closes
161
160
  */
162
161
  onClose?: () => void;
162
+ /**
163
+ * Callback that exposes chat controls for external manipulation
164
+ * Useful for programmatically setting input values
165
+ */
166
+ onControlsReady?: (controls: {
167
+ setInput: (value: string) => void;
168
+ }) => void;
163
169
  /**
164
170
  * Additional CSS class name for custom styling
165
171
  */
@@ -232,7 +238,7 @@ interface WidgetSettings {
232
238
  * }
233
239
  * ```
234
240
  */
235
- declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
241
+ declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, onControlsReady, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
236
242
 
237
243
  interface ChatBubbleProps {
238
244
  isOpen: boolean;
@@ -275,7 +281,7 @@ interface UseHissunoChatOptions {
275
281
  projectId: string;
276
282
  /** JWT token for secure widget authentication */
277
283
  widgetToken?: string;
278
- /** Custom API endpoint URL (default: '/api/agent') */
284
+ /** Custom API endpoint URL (default: '/api/integrations/widget/chat') */
279
285
  apiUrl?: string;
280
286
  /** Initial assistant message shown when chat opens */
281
287
  initialMessage?: string;
@@ -287,6 +293,8 @@ interface UseHissunoChatOptions {
287
293
  userMetadata?: Record<string, string>;
288
294
  /** Custom session ID (auto-generated if not provided) */
289
295
  sessionId?: string;
296
+ /** Override the knowledge package used for this chat session (for testing) */
297
+ packageId?: string;
290
298
  /** Inactivity timeout in ms before auto-closing session (default: 30 minutes) */
291
299
  inactivityTimeout?: number;
292
300
  /** Callback when session is closed */
@@ -352,7 +360,7 @@ interface UseHissunoChatReturn {
352
360
  * @param options - Hook configuration options
353
361
  * @returns Chat state and control functions
354
362
  */
355
- declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
363
+ declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, packageId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
356
364
 
357
365
  interface ChatPopupProps {
358
366
  isOpen: boolean;
package/dist/index.js CHANGED
@@ -957,15 +957,15 @@ function ChatPopup({
957
957
  },
958
958
  children: [
959
959
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
960
- "input",
960
+ "textarea",
961
961
  {
962
- type: "text",
963
962
  value: input,
964
963
  onChange: (e) => setInput(e.target.value),
965
964
  onKeyDown: handleKeyDown,
966
965
  placeholder,
967
966
  disabled: isLoading,
968
967
  "aria-label": "Type your message",
968
+ rows: 1,
969
969
  style: {
970
970
  flex: 1,
971
971
  padding: "10px 14px",
@@ -975,7 +975,12 @@ function ChatPopup({
975
975
  color: textColor,
976
976
  fontSize: 14,
977
977
  outline: "none",
978
- fontFamily: "system-ui, -apple-system, sans-serif"
978
+ fontFamily: "system-ui, -apple-system, sans-serif",
979
+ resize: "none",
980
+ minHeight: 40,
981
+ maxHeight: 120,
982
+ overflow: "auto",
983
+ lineHeight: "20px"
979
984
  }
980
985
  }
981
986
  ),
@@ -1099,7 +1104,7 @@ function ChatSidepanel({
1099
1104
  position: "fixed",
1100
1105
  top: 0,
1101
1106
  right: 0,
1102
- width: 400,
1107
+ width: 480,
1103
1108
  height: "100vh",
1104
1109
  display: "flex",
1105
1110
  flexDirection: "column",
@@ -1255,15 +1260,15 @@ function ChatSidepanel({
1255
1260
  },
1256
1261
  children: [
1257
1262
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1258
- "input",
1263
+ "textarea",
1259
1264
  {
1260
- type: "text",
1261
1265
  value: input,
1262
1266
  onChange: (e) => setInput(e.target.value),
1263
1267
  onKeyDown: handleKeyDown,
1264
1268
  placeholder,
1265
1269
  disabled: isLoading,
1266
1270
  "aria-label": "Type your message",
1271
+ rows: 1,
1267
1272
  style: {
1268
1273
  flex: 1,
1269
1274
  padding: "10px 14px",
@@ -1273,7 +1278,12 @@ function ChatSidepanel({
1273
1278
  color: textColor,
1274
1279
  fontSize: 14,
1275
1280
  outline: "none",
1276
- fontFamily: "system-ui, -apple-system, sans-serif"
1281
+ fontFamily: "system-ui, -apple-system, sans-serif",
1282
+ resize: "none",
1283
+ minHeight: 40,
1284
+ maxHeight: 120,
1285
+ overflow: "auto",
1286
+ lineHeight: "20px"
1277
1287
  }
1278
1288
  }
1279
1289
  ),
@@ -1638,9 +1648,8 @@ function ChatDialog({
1638
1648
  },
1639
1649
  children: [
1640
1650
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1641
- "input",
1651
+ "textarea",
1642
1652
  {
1643
- type: "text",
1644
1653
  value: input,
1645
1654
  onChange: (e) => setInput(e.target.value),
1646
1655
  onKeyDown: handleKeyDown,
@@ -1648,6 +1657,7 @@ function ChatDialog({
1648
1657
  disabled: isLoading,
1649
1658
  autoFocus: true,
1650
1659
  "aria-label": "Type your message",
1660
+ rows: 1,
1651
1661
  style: {
1652
1662
  flex: 1,
1653
1663
  padding: "12px 16px",
@@ -1657,7 +1667,12 @@ function ChatDialog({
1657
1667
  color: textColor,
1658
1668
  fontSize: 14,
1659
1669
  outline: "none",
1660
- fontFamily: "system-ui, -apple-system, sans-serif"
1670
+ fontFamily: "system-ui, -apple-system, sans-serif",
1671
+ resize: "none",
1672
+ minHeight: 44,
1673
+ maxHeight: 120,
1674
+ overflow: "auto",
1675
+ lineHeight: "20px"
1661
1676
  }
1662
1677
  }
1663
1678
  ),
@@ -2012,12 +2027,13 @@ function deleteSessionFromRegistry(projectId, userId, sessionId) {
2012
2027
  function useHissunoChat({
2013
2028
  projectId,
2014
2029
  widgetToken,
2015
- apiUrl = "/api/agent",
2030
+ apiUrl = "/api/integrations/widget/chat",
2016
2031
  initialMessage,
2017
2032
  headers = {},
2018
2033
  userId,
2019
2034
  userMetadata,
2020
2035
  sessionId: providedSessionId,
2036
+ packageId,
2021
2037
  inactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT,
2022
2038
  onSessionClose
2023
2039
  }) {
@@ -2171,7 +2187,7 @@ function useHissunoChat({
2171
2187
  }, [apiUrl, projectId, sessionId, connectToStream]);
2172
2188
  (0, import_react4.useEffect)(() => {
2173
2189
  if (sessionClosedRef.current || !sessionId) return;
2174
- const updatesUrl = `${apiUrl}/session/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
2190
+ const updatesUrl = `${apiUrl}/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
2175
2191
  const connectUpdates = () => {
2176
2192
  if (updatesEventSourceRef.current) return;
2177
2193
  const eventSource = new EventSource(updatesUrl);
@@ -2328,7 +2344,7 @@ function useHissunoChat({
2328
2344
  inactivityTimerRef.current = null;
2329
2345
  }
2330
2346
  try {
2331
- await fetch(`${apiUrl}/session/close`, {
2347
+ await fetch(`${apiUrl}/close`, {
2332
2348
  method: "POST",
2333
2349
  headers: {
2334
2350
  "Content-Type": "application/json",
@@ -2343,7 +2359,7 @@ function useHissunoChat({
2343
2359
  }, [sessionId, apiUrl, projectId, headers, onSessionClose]);
2344
2360
  const cancelChat = (0, import_react4.useCallback)(async () => {
2345
2361
  try {
2346
- const cancelUrl = `${apiUrl}/cancel`;
2362
+ const cancelUrl = `${apiUrl}/stream/cancel`;
2347
2363
  const response = await fetch(cancelUrl, {
2348
2364
  method: "POST",
2349
2365
  headers: {
@@ -2363,6 +2379,7 @@ function useHissunoChat({
2363
2379
  eventSourceRef.current.close();
2364
2380
  eventSourceRef.current = null;
2365
2381
  }
2382
+ isConnectingRef.current = false;
2366
2383
  setIsLoading(false);
2367
2384
  setIsStreaming(false);
2368
2385
  setStreamingContent("");
@@ -2389,7 +2406,7 @@ function useHissunoChat({
2389
2406
  (0, import_react4.useEffect)(() => {
2390
2407
  const handleBeforeUnload = () => {
2391
2408
  if (!sessionId || sessionClosedRef.current) return;
2392
- const url = `${apiUrl}/session/close`;
2409
+ const url = `${apiUrl}/close`;
2393
2410
  const data = JSON.stringify({ sessionId, projectId });
2394
2411
  navigator.sendBeacon(url, data);
2395
2412
  };
@@ -2437,7 +2454,8 @@ function useHissunoChat({
2437
2454
  pageUrl,
2438
2455
  pageTitle,
2439
2456
  sessionId,
2440
- widgetToken
2457
+ widgetToken,
2458
+ packageId
2441
2459
  })
2442
2460
  });
2443
2461
  if (!response.ok) {
@@ -2455,7 +2473,7 @@ function useHissunoChat({
2455
2473
  setIsLoading(false);
2456
2474
  }
2457
2475
  },
2458
- [input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, connectToStream]
2476
+ [input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, packageId, connectToStream]
2459
2477
  );
2460
2478
  return (0, import_react4.useMemo)(
2461
2479
  () => ({
@@ -2584,7 +2602,7 @@ function useResolvedTheme(theme) {
2584
2602
 
2585
2603
  // src/HissunoWidget.tsx
2586
2604
  var import_jsx_runtime9 = require("react/jsx-runtime");
2587
- var DEFAULT_API_URL = "/api/agent";
2605
+ var DEFAULT_API_URL = "/api/integrations/widget/chat";
2588
2606
  function HissunoWidget({
2589
2607
  projectId,
2590
2608
  widgetToken,
@@ -2608,6 +2626,7 @@ function HissunoWidget({
2608
2626
  defaultOpen = false,
2609
2627
  onOpen,
2610
2628
  onClose,
2629
+ onControlsReady,
2611
2630
  className,
2612
2631
  headers = {}
2613
2632
  }) {
@@ -2619,7 +2638,7 @@ function HissunoWidget({
2619
2638
  blocked,
2620
2639
  loading: settingsLoading,
2621
2640
  error: settingsError
2622
- } = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl, widgetToken);
2641
+ } = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl ?? DEFAULT_API_URL, widgetToken);
2623
2642
  const resolveTrigger = () => {
2624
2643
  if (propTrigger) return propTrigger;
2625
2644
  if (renderTrigger) return "headless";
@@ -2666,6 +2685,9 @@ function HissunoWidget({
2666
2685
  userId,
2667
2686
  userMetadata
2668
2687
  });
2688
+ (0, import_react7.useEffect)(() => {
2689
+ onControlsReady?.({ setInput });
2690
+ }, [onControlsReady, setInput]);
2669
2691
  const canShowHistory = !!userId;
2670
2692
  const handleOpenHistory = (0, import_react7.useCallback)(() => {
2671
2693
  if (!canShowHistory) return;
@@ -2858,7 +2880,7 @@ function useWidgetSettings(projectId, enabled, apiUrl, widgetToken) {
2858
2880
  }
2859
2881
  setLoading(true);
2860
2882
  setError(false);
2861
- const settingsUrl = `${apiUrl.replace(/\/api\/agent\/?$/, "/api/integrations/widget")}?projectId=${encodeURIComponent(projectId)}`;
2883
+ const settingsUrl = `${apiUrl.replace(/\/chat\/?$/, "")}?projectId=${encodeURIComponent(projectId)}`;
2862
2884
  const controller = new AbortController();
2863
2885
  fetch(settingsUrl, {
2864
2886
  signal: controller.signal
package/dist/index.mjs CHANGED
@@ -917,15 +917,15 @@ function ChatPopup({
917
917
  },
918
918
  children: [
919
919
  /* @__PURE__ */ jsx6(
920
- "input",
920
+ "textarea",
921
921
  {
922
- type: "text",
923
922
  value: input,
924
923
  onChange: (e) => setInput(e.target.value),
925
924
  onKeyDown: handleKeyDown,
926
925
  placeholder,
927
926
  disabled: isLoading,
928
927
  "aria-label": "Type your message",
928
+ rows: 1,
929
929
  style: {
930
930
  flex: 1,
931
931
  padding: "10px 14px",
@@ -935,7 +935,12 @@ function ChatPopup({
935
935
  color: textColor,
936
936
  fontSize: 14,
937
937
  outline: "none",
938
- fontFamily: "system-ui, -apple-system, sans-serif"
938
+ fontFamily: "system-ui, -apple-system, sans-serif",
939
+ resize: "none",
940
+ minHeight: 40,
941
+ maxHeight: 120,
942
+ overflow: "auto",
943
+ lineHeight: "20px"
939
944
  }
940
945
  }
941
946
  ),
@@ -1059,7 +1064,7 @@ function ChatSidepanel({
1059
1064
  position: "fixed",
1060
1065
  top: 0,
1061
1066
  right: 0,
1062
- width: 400,
1067
+ width: 480,
1063
1068
  height: "100vh",
1064
1069
  display: "flex",
1065
1070
  flexDirection: "column",
@@ -1215,15 +1220,15 @@ function ChatSidepanel({
1215
1220
  },
1216
1221
  children: [
1217
1222
  /* @__PURE__ */ jsx7(
1218
- "input",
1223
+ "textarea",
1219
1224
  {
1220
- type: "text",
1221
1225
  value: input,
1222
1226
  onChange: (e) => setInput(e.target.value),
1223
1227
  onKeyDown: handleKeyDown,
1224
1228
  placeholder,
1225
1229
  disabled: isLoading,
1226
1230
  "aria-label": "Type your message",
1231
+ rows: 1,
1227
1232
  style: {
1228
1233
  flex: 1,
1229
1234
  padding: "10px 14px",
@@ -1233,7 +1238,12 @@ function ChatSidepanel({
1233
1238
  color: textColor,
1234
1239
  fontSize: 14,
1235
1240
  outline: "none",
1236
- fontFamily: "system-ui, -apple-system, sans-serif"
1241
+ fontFamily: "system-ui, -apple-system, sans-serif",
1242
+ resize: "none",
1243
+ minHeight: 40,
1244
+ maxHeight: 120,
1245
+ overflow: "auto",
1246
+ lineHeight: "20px"
1237
1247
  }
1238
1248
  }
1239
1249
  ),
@@ -1598,9 +1608,8 @@ function ChatDialog({
1598
1608
  },
1599
1609
  children: [
1600
1610
  /* @__PURE__ */ jsx8(
1601
- "input",
1611
+ "textarea",
1602
1612
  {
1603
- type: "text",
1604
1613
  value: input,
1605
1614
  onChange: (e) => setInput(e.target.value),
1606
1615
  onKeyDown: handleKeyDown,
@@ -1608,6 +1617,7 @@ function ChatDialog({
1608
1617
  disabled: isLoading,
1609
1618
  autoFocus: true,
1610
1619
  "aria-label": "Type your message",
1620
+ rows: 1,
1611
1621
  style: {
1612
1622
  flex: 1,
1613
1623
  padding: "12px 16px",
@@ -1617,7 +1627,12 @@ function ChatDialog({
1617
1627
  color: textColor,
1618
1628
  fontSize: 14,
1619
1629
  outline: "none",
1620
- fontFamily: "system-ui, -apple-system, sans-serif"
1630
+ fontFamily: "system-ui, -apple-system, sans-serif",
1631
+ resize: "none",
1632
+ minHeight: 44,
1633
+ maxHeight: 120,
1634
+ overflow: "auto",
1635
+ lineHeight: "20px"
1621
1636
  }
1622
1637
  }
1623
1638
  ),
@@ -1972,12 +1987,13 @@ function deleteSessionFromRegistry(projectId, userId, sessionId) {
1972
1987
  function useHissunoChat({
1973
1988
  projectId,
1974
1989
  widgetToken,
1975
- apiUrl = "/api/agent",
1990
+ apiUrl = "/api/integrations/widget/chat",
1976
1991
  initialMessage,
1977
1992
  headers = {},
1978
1993
  userId,
1979
1994
  userMetadata,
1980
1995
  sessionId: providedSessionId,
1996
+ packageId,
1981
1997
  inactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT,
1982
1998
  onSessionClose
1983
1999
  }) {
@@ -2131,7 +2147,7 @@ function useHissunoChat({
2131
2147
  }, [apiUrl, projectId, sessionId, connectToStream]);
2132
2148
  useEffect4(() => {
2133
2149
  if (sessionClosedRef.current || !sessionId) return;
2134
- const updatesUrl = `${apiUrl}/session/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
2150
+ const updatesUrl = `${apiUrl}/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
2135
2151
  const connectUpdates = () => {
2136
2152
  if (updatesEventSourceRef.current) return;
2137
2153
  const eventSource = new EventSource(updatesUrl);
@@ -2288,7 +2304,7 @@ function useHissunoChat({
2288
2304
  inactivityTimerRef.current = null;
2289
2305
  }
2290
2306
  try {
2291
- await fetch(`${apiUrl}/session/close`, {
2307
+ await fetch(`${apiUrl}/close`, {
2292
2308
  method: "POST",
2293
2309
  headers: {
2294
2310
  "Content-Type": "application/json",
@@ -2303,7 +2319,7 @@ function useHissunoChat({
2303
2319
  }, [sessionId, apiUrl, projectId, headers, onSessionClose]);
2304
2320
  const cancelChat = useCallback3(async () => {
2305
2321
  try {
2306
- const cancelUrl = `${apiUrl}/cancel`;
2322
+ const cancelUrl = `${apiUrl}/stream/cancel`;
2307
2323
  const response = await fetch(cancelUrl, {
2308
2324
  method: "POST",
2309
2325
  headers: {
@@ -2323,6 +2339,7 @@ function useHissunoChat({
2323
2339
  eventSourceRef.current.close();
2324
2340
  eventSourceRef.current = null;
2325
2341
  }
2342
+ isConnectingRef.current = false;
2326
2343
  setIsLoading(false);
2327
2344
  setIsStreaming(false);
2328
2345
  setStreamingContent("");
@@ -2349,7 +2366,7 @@ function useHissunoChat({
2349
2366
  useEffect4(() => {
2350
2367
  const handleBeforeUnload = () => {
2351
2368
  if (!sessionId || sessionClosedRef.current) return;
2352
- const url = `${apiUrl}/session/close`;
2369
+ const url = `${apiUrl}/close`;
2353
2370
  const data = JSON.stringify({ sessionId, projectId });
2354
2371
  navigator.sendBeacon(url, data);
2355
2372
  };
@@ -2397,7 +2414,8 @@ function useHissunoChat({
2397
2414
  pageUrl,
2398
2415
  pageTitle,
2399
2416
  sessionId,
2400
- widgetToken
2417
+ widgetToken,
2418
+ packageId
2401
2419
  })
2402
2420
  });
2403
2421
  if (!response.ok) {
@@ -2415,7 +2433,7 @@ function useHissunoChat({
2415
2433
  setIsLoading(false);
2416
2434
  }
2417
2435
  },
2418
- [input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, connectToStream]
2436
+ [input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, packageId, connectToStream]
2419
2437
  );
2420
2438
  return useMemo(
2421
2439
  () => ({
@@ -2544,7 +2562,7 @@ function useResolvedTheme(theme) {
2544
2562
 
2545
2563
  // src/HissunoWidget.tsx
2546
2564
  import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2547
- var DEFAULT_API_URL = "/api/agent";
2565
+ var DEFAULT_API_URL = "/api/integrations/widget/chat";
2548
2566
  function HissunoWidget({
2549
2567
  projectId,
2550
2568
  widgetToken,
@@ -2568,6 +2586,7 @@ function HissunoWidget({
2568
2586
  defaultOpen = false,
2569
2587
  onOpen,
2570
2588
  onClose,
2589
+ onControlsReady,
2571
2590
  className,
2572
2591
  headers = {}
2573
2592
  }) {
@@ -2579,7 +2598,7 @@ function HissunoWidget({
2579
2598
  blocked,
2580
2599
  loading: settingsLoading,
2581
2600
  error: settingsError
2582
- } = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl, widgetToken);
2601
+ } = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl ?? DEFAULT_API_URL, widgetToken);
2583
2602
  const resolveTrigger = () => {
2584
2603
  if (propTrigger) return propTrigger;
2585
2604
  if (renderTrigger) return "headless";
@@ -2626,6 +2645,9 @@ function HissunoWidget({
2626
2645
  userId,
2627
2646
  userMetadata
2628
2647
  });
2648
+ useEffect7(() => {
2649
+ onControlsReady?.({ setInput });
2650
+ }, [onControlsReady, setInput]);
2629
2651
  const canShowHistory = !!userId;
2630
2652
  const handleOpenHistory = useCallback5(() => {
2631
2653
  if (!canShowHistory) return;
@@ -2818,7 +2840,7 @@ function useWidgetSettings(projectId, enabled, apiUrl, widgetToken) {
2818
2840
  }
2819
2841
  setLoading(true);
2820
2842
  setError(false);
2821
- const settingsUrl = `${apiUrl.replace(/\/api\/agent\/?$/, "/api/integrations/widget")}?projectId=${encodeURIComponent(projectId)}`;
2843
+ const settingsUrl = `${apiUrl.replace(/\/chat\/?$/, "")}?projectId=${encodeURIComponent(projectId)}`;
2822
2844
  const controller = new AbortController();
2823
2845
  fetch(settingsUrl, {
2824
2846
  signal: controller.signal
package/dist/styles.css CHANGED
@@ -105,27 +105,14 @@
105
105
  animation: hissuno-fade-in-backdrop 0.2s ease-out;
106
106
  }
107
107
 
108
- /* Messages container */
108
+ /* Messages container - hide scrollbar but keep scrolling */
109
109
  .hissuno-messages {
110
- scrollbar-width: thin;
111
- scrollbar-color: rgba(155, 155, 155, 0.5) transparent;
110
+ scrollbar-width: none; /* Firefox */
111
+ -ms-overflow-style: none; /* IE and Edge */
112
112
  }
113
113
 
114
114
  .hissuno-messages::-webkit-scrollbar {
115
- width: 6px;
116
- }
117
-
118
- .hissuno-messages::-webkit-scrollbar-track {
119
- background: transparent;
120
- }
121
-
122
- .hissuno-messages::-webkit-scrollbar-thumb {
123
- background-color: rgba(155, 155, 155, 0.5);
124
- border-radius: 3px;
125
- }
126
-
127
- .hissuno-messages::-webkit-scrollbar-thumb:hover {
128
- background-color: rgba(155, 155, 155, 0.7);
115
+ display: none; /* Chrome, Safari, Opera */
129
116
  }
130
117
 
131
118
  /* Loading dots animation */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hissuno/widget",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Embeddable AI-powered support chat widget for Hissuno platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",